<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr">
		<id>https://wiki.siladel.fr/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Goldron</id>
		<title>SILADEL - Contributions de l’utilisateur [fr]</title>
		<link rel="self" type="application/atom+xml" href="https://wiki.siladel.fr/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Goldron"/>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Sp%C3%A9cial:Contributions/Goldron"/>
		<updated>2026-09-12T04:38:39Z</updated>
		<subtitle>Contributions de l’utilisateur</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=README&amp;diff=555</id>
		<title>README</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=README&amp;diff=555"/>
				<updated>2026-08-02T13:02:36Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : Page créée avec « = STRIPEACCOUNTING FOR Dolibarr ERP CRM =  '''StripeAccounting''' reconciles real Stripe movements — per-transaction and subscription/service fees, refunds, disputes... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= STRIPEACCOUNTING FOR [[Dolibarr ERP CRM]] =&lt;br /&gt;
&lt;br /&gt;
'''StripeAccounting''' reconciles real Stripe movements — per-transaction and subscription/service fees, refunds, disputes (chargebacks) and payouts — with Dolibarr's Stripe intermediary financial account, and automatically generates the missing entries or bank movements.&lt;br /&gt;
&lt;br /&gt;
This module is complementary to the official Stripe module: it never creates payments, invoices, checkout sessions or payment webhooks. It only reads the Stripe API and posts the accounting entries the official module doesn't cover.&lt;br /&gt;
&lt;br /&gt;
== How it works ==&lt;br /&gt;
&lt;br /&gt;
# The module pulls Stripe's Balance Transactions, Charges, Refunds, Disputes and Payouts through the Stripe API, reusing the API key and mode (test/live) already configured by the official Stripe module.&lt;br /&gt;
# Every Stripe object is stored once in its own table (&amp;lt;code&amp;gt;llx_stripeaccounting_transaction&amp;lt;/code&amp;gt;), keyed by its Stripe id, so a transaction is never processed twice even if the sync runs repeatedly.&lt;br /&gt;
# For each new object, the matching accounting treatment is triggered automatically:&lt;br /&gt;
&lt;br /&gt;
* '''Per-transaction fees''' and '''subscription/service fees''' (Radar, Billing, Connect...):&lt;br /&gt;
*: The module creates the matching bank movement on the Stripe account (with its accounting counterpart already set), but '''does not post the ledger entry itself'''.&lt;br /&gt;
*: Dolibarr's own native &amp;quot;Transfer to accounting&amp;quot; button generates it afterwards, exactly like any other bank movement.&lt;br /&gt;
*: Exception: under French VAT mode, the full entry (fee + VAT) is still posted directly by the module, with no dedicated bank movement.&lt;br /&gt;
&lt;br /&gt;
* '''Payouts''':&lt;br /&gt;
*: The module creates a real internal bank transfer between the Stripe account and the main bank account.&lt;br /&gt;
*: Dolibarr's native transfer-to-accounting step posts the entry on both sides.&lt;br /&gt;
&lt;br /&gt;
* '''Refunds''':&lt;br /&gt;
*: Reverse the original charge's entry when the related invoice/payment can be traced back.&lt;br /&gt;
*: Otherwise the transaction is flagged for manual review instead of guessing an account.&lt;br /&gt;
&lt;br /&gt;
* '''Disputes / chargebacks''':&lt;br /&gt;
*: The disputed amount is posted immediately to a dedicated loss account, plus the dispute's own Stripe fee.&lt;br /&gt;
&lt;br /&gt;
* '''Stripe balance corrections''' (&amp;lt;code&amp;gt;adjustment&amp;lt;/code&amp;gt;, an automatic refund after a payment ultimately failed):&lt;br /&gt;
*: Recorded so they stay visible, but never posted automatically — their sign and cause vary too much to be posted reliably without human review.&lt;br /&gt;
&lt;br /&gt;
* '''Optional VAT handling on fees''':&lt;br /&gt;
*: No VAT, French VAT, or intracommunity reverse charge.&lt;br /&gt;
*: The reverse charge mode posts a symmetric, zero-net VAT pair immediately.&lt;br /&gt;
&lt;br /&gt;
# A dashboard shows:&lt;br /&gt;
#* Stripe balance&lt;br /&gt;
#* unreconciled transactions&lt;br /&gt;
#* monthly fees&lt;br /&gt;
#* pending payouts&lt;br /&gt;
#* manual &amp;quot;Sync now&amp;quot; action&lt;br /&gt;
&lt;br /&gt;
#: A cron job runs the same reconciliation on a schedule.&lt;br /&gt;
&lt;br /&gt;
# For a Stripe account '''not connected through the API''' (for example another storefront with its own merchant account), a CSV import page processes Stripe's &amp;quot;Balance history&amp;quot; export (one file covering every movement type) under the same idempotency guarantees.&lt;br /&gt;
#: The import button stays disabled until the minimal configuration is complete, exactly like the sync button.&lt;br /&gt;
&lt;br /&gt;
== Setup ==&lt;br /&gt;
&lt;br /&gt;
'''Home &amp;gt; Setup &amp;gt; Modules &amp;gt; StripeAccounting'''&lt;br /&gt;
&lt;br /&gt;
* '''Stripe financial account''' and '''Main bank account'''&lt;br /&gt;
*: Editable selectors that write directly to the official Stripe module's own constants (no local copy, so no risk of drift).&lt;br /&gt;
&lt;br /&gt;
* '''Fees account'''&lt;br /&gt;
*: Accounting account for Stripe commissions (example: 627xxx).&lt;br /&gt;
&lt;br /&gt;
* '''Disputes account'''&lt;br /&gt;
*: Accounting account for chargeback losses (example: 658xxx).&lt;br /&gt;
&lt;br /&gt;
* '''Stripe supplier thirdparty'''&lt;br /&gt;
*: Used to post subscription/service fees (Radar, Billing...) against this thirdparty's own supplier accounting code.&lt;br /&gt;
&lt;br /&gt;
* '''VAT mode'''&lt;br /&gt;
*: None, French VAT, or intracommunity reverse charge, with a configurable rate.&lt;br /&gt;
&lt;br /&gt;
* '''Sync frequency'''&lt;br /&gt;
*: How often the scheduled job runs.&lt;br /&gt;
&lt;br /&gt;
The module refuses to run any synchronization while the minimal configuration above is incomplete — it aborts up-front rather than posting partial or guessed entries.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border:1px solid #e00; background:#fee; padding:10px;&amp;quot;&amp;gt;&lt;br /&gt;
'''⚠️ Warning'''&lt;br /&gt;
&lt;br /&gt;
Do not enable '''&amp;quot;Enable the auto recording of Stripe payouts&amp;quot;''' on the official Stripe module's setup page (Setup &amp;gt; Modules &amp;gt; Stripe).&lt;br /&gt;
&lt;br /&gt;
It makes the official module's own webhook create a bank movement for every Stripe payout — exactly what this module already does, but without any idempotency of its own.&lt;br /&gt;
&lt;br /&gt;
Having both mechanisms enabled at once would each create their own bank movement for the same payout, resulting in a duplicate.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Scheduled task (cron) ==&lt;br /&gt;
&lt;br /&gt;
Activating the module registers a scheduled job (&amp;lt;code&amp;gt;StripeAccountingSync&amp;lt;/code&amp;gt;) in:&lt;br /&gt;
&lt;br /&gt;
'''Home &amp;gt; Setup &amp;gt; Modules &amp;gt; Scheduled jobs'''&lt;br /&gt;
&lt;br /&gt;
However, two things are required for it to actually run unattended:&lt;br /&gt;
&lt;br /&gt;
=== 1. Enable the job ===&lt;br /&gt;
&lt;br /&gt;
Dolibarr creates it disabled by default.&lt;br /&gt;
&lt;br /&gt;
Open it from the scheduled jobs list and tick '''Active'''.&lt;br /&gt;
&lt;br /&gt;
=== 2. Trigger Dolibarr's scheduler periodically ===&lt;br /&gt;
&lt;br /&gt;
Nothing calls it automatically.&lt;br /&gt;
&lt;br /&gt;
You need an external cron hitting one of the following:&lt;br /&gt;
&lt;br /&gt;
'''Module standalone CLI script:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
*/15 * * * * php /path/to/htdocs/custom/stripeaccounting/cron/stripe_sync.php &amp;gt;&amp;gt; /var/log/stripeaccounting.log 2&amp;gt;&amp;amp;1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Dolibarr generic URL-based job runner:'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
*/15 * * * * curl &amp;quot;https://your-dolibarr-url/public/cron/cron_run_jobs_by_url.php?securitykey=YOUR_KEY&amp;amp;userlogin=YOUR_LOGIN&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Without one of these two crontab entries, synchronization only happens when someone clicks '''&amp;quot;Sync now&amp;quot;''' on the dashboard.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Dolibarr 17+&lt;br /&gt;
* PHP 7.2 to 8.5 (no syntax specific to a recent PHP version is used, to stay compatible across that whole range)&lt;br /&gt;
* Official Stripe module enabled and configured:&lt;br /&gt;
** API keys&lt;br /&gt;
** financial account&lt;br /&gt;
* Double-entry Accounting module, for the &amp;lt;code&amp;gt;llx_accounting_bookkeeping&amp;lt;/code&amp;gt; table&lt;br /&gt;
&lt;br /&gt;
== Credits ==&lt;br /&gt;
&lt;br /&gt;
StripeAccounting is developed and maintained by '''SILADEL'''.&lt;br /&gt;
&lt;br /&gt;
=== License ===&lt;br /&gt;
&lt;br /&gt;
GPL v3 or any later version.&lt;br /&gt;
&lt;br /&gt;
=== SILADEL ===&lt;br /&gt;
&lt;br /&gt;
'''SILADEL'''  &lt;br /&gt;
7 ch des coquelicots  &lt;br /&gt;
81990 Cambon France&lt;br /&gt;
&lt;br /&gt;
E-mail: [mailto:info@siladel.fr info@siladel.fr]&lt;br /&gt;
&lt;br /&gt;
Website: [https://www.siladel.fr www.siladel.fr]&lt;br /&gt;
&lt;br /&gt;
== Documentation ==&lt;br /&gt;
&lt;br /&gt;
* [[Documentation Wiki|WIKI Documentation]]&lt;br /&gt;
&lt;br /&gt;
=== Support request ===&lt;br /&gt;
&lt;br /&gt;
[mailto:info@siladel.fr Support request]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[File:SILADELogo.svg|84px|SILADEL]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Developed by [https://www.siladel.fr SILADEL] — Author: IGREJA David&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Stripeaccounting&amp;diff=554</id>
		<title>Stripeaccounting</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Stripeaccounting&amp;diff=554"/>
				<updated>2026-08-02T12:41:12Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:StripeAccounting — Documentation technique}}&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Us.png|32px|link=Stripeaccounting/en|English documentation]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border:1px solid #c8ccd1; background:#f8f9fa; border-radius:4px; padding:1em 1.2em; margin:0 0 1.5em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''StripeAccounting''' est un module Dolibarr de '''rapprochement comptable Stripe'''.&lt;br /&gt;
&lt;br /&gt;
Il lit l'API Stripe (ou un export CSV), repère les mouvements que le module Stripe officiel ne comptabilise pas — frais, remboursements, litiges, virements — et pose les écritures manquantes.&lt;br /&gt;
&lt;br /&gt;
: '''Compatibilité''' — Dolibarr 17+, PHP 7.2 → 8.5&lt;br /&gt;
: '''Dépend de''' — modules Stripe, Banque, Comptabilité en partie double&lt;br /&gt;
: '''Voir aussi''' — [[README-fr|Installation et guide utilisateur]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== 1. Principes de fonctionnement ==&lt;br /&gt;
&lt;br /&gt;
Quatre règles gouvernent tout le module.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:22%;&amp;quot; | Principe !! Ce que ça veut dire&lt;br /&gt;
|-&lt;br /&gt;
| '''Complémentaire''' || Le module ne crée aucun paiement, aucune facture, aucun webhook. Il lit Stripe et complète la comptabilité, rien de plus.&lt;br /&gt;
|-&lt;br /&gt;
| '''Idempotent''' || Chaque objet Stripe n'est traité qu'une fois, quel que soit le nombre de relances de la synchronisation.&lt;br /&gt;
|-&lt;br /&gt;
| '''Jamais de devinette''' || Si une opération ne peut pas être rattachée avec certitude, rien n'est posté : la ligne passe en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; pour revue manuelle.&lt;br /&gt;
|-&lt;br /&gt;
| '''Configuration bloquante''' || Tant que la configuration minimale est incomplète, aucune synchronisation ne démarre (ni bouton, ni cron, ni import).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2. Prérequis ==&lt;br /&gt;
&lt;br /&gt;
=== Modules Dolibarr requis ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Module !! Ce qu'il apporte&lt;br /&gt;
|-&lt;br /&gt;
| '''Stripe''' (&amp;lt;code&amp;gt;modStripe&amp;lt;/code&amp;gt;) || Clé API, mode test/live, compte financier Stripe&lt;br /&gt;
|-&lt;br /&gt;
| '''Banque''' (&amp;lt;code&amp;gt;modBanque&amp;lt;/code&amp;gt;) || Tables &amp;lt;code&amp;gt;llx_bank&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;llx_bank_account&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| '''Comptabilité en partie double''' (&amp;lt;code&amp;gt;modAccounting&amp;lt;/code&amp;gt;) || Table &amp;lt;code&amp;gt;llx_accounting_bookkeeping&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Réglage Dolibarr indispensable ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ACCOUNTING_ACCOUNT_TRANSFER_CASH&amp;lt;/code&amp;gt; doit être renseigné dans '''Comptabilité → Configuration → Comptes par défaut'''. Sans lui, le virement interne généré par les payouts ne peut pas être transféré en comptabilité (limite de Dolibarr, pas du module).&lt;br /&gt;
&lt;br /&gt;
l’option s'appelle : '''Compte comptable par défaut pour les virements internes'''&lt;br /&gt;
&lt;br /&gt;
=== Notes ===&lt;br /&gt;
&lt;br /&gt;
* Le SDK PHP Stripe n'est pas dupliqué : le module réutilise la copie du cœur (&amp;lt;code&amp;gt;includes/stripe/stripe-php/&amp;lt;/code&amp;gt;).&lt;br /&gt;
* Le code évite volontairement toute syntaxe PHP postérieure à 7.2 (pas de &amp;lt;code&amp;gt;match&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;?-&amp;gt;&amp;lt;/code&amp;gt;, enums, propriétés typées, &amp;lt;code&amp;gt;str_contains&amp;lt;/code&amp;gt;…) pour couvrir toute la plage 7.2 → 8.5.&lt;br /&gt;
&lt;br /&gt;
== 3. Arborescence ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
custom/stripeaccounting/&lt;br /&gt;
├── core/modules/modStripeAccounting.class.php   Descripteur (droits, menus, cron, constantes)&lt;br /&gt;
├── class/&lt;br /&gt;
│   ├── StripeApi.class.php                      Wrapper SDK Stripe (lecture seule)&lt;br /&gt;
│   ├── StripeRepository.class.php               Accès SQL + idempotence&lt;br /&gt;
│   ├── StripeLogger.class.php                   Journalisation&lt;br /&gt;
│   ├── StripeAccounting.class.php               Génération des écritures&lt;br /&gt;
│   ├── StripePayout.class.php                   Rapprochement des virements&lt;br /&gt;
│   ├── StripeSync.class.php                     Orchestrateur (point d'entrée du cron)&lt;br /&gt;
│   ├── StripeCsvImporter.class.php              Import CSV&lt;br /&gt;
│   └── actions_stripeaccounting.class.php       Hook 'bankcard'&lt;br /&gt;
├── admin/setup.php                              Configuration&lt;br /&gt;
├── import.php                                   Import CSV&lt;br /&gt;
├── dashboard.php                                Tableau de bord&lt;br /&gt;
├── transaction_list.php                         Liste des transactions&lt;br /&gt;
├── cron/stripe_sync.php                         Point d'entrée CLI&lt;br /&gt;
├── lib/stripeaccounting.lib.php&lt;br /&gt;
├── sql/&lt;br /&gt;
├── langs/{fr_FR,en_US,es_ES,it_IT,de_DE}/&lt;br /&gt;
└── css/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sens des dépendances ===&lt;br /&gt;
&lt;br /&gt;
: pages et hook → &amp;lt;code&amp;gt;StripeSync&amp;lt;/code&amp;gt; → (&amp;lt;code&amp;gt;StripeApi&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StripeRepository&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StripeAccounting&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StripePayout&amp;lt;/code&amp;gt;) → &amp;lt;code&amp;gt;StripeLogger&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:26%;&amp;quot; | Classe !! Rôle&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeApi&amp;lt;/code&amp;gt; || Interroge le SDK Stripe (balance transactions, charges, remboursements, litiges, payouts) avec pagination automatique. Aucun accès base, aucune écriture.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeRepository&amp;lt;/code&amp;gt; || Tout le SQL des deux tables du module. &amp;lt;code&amp;gt;upsertTransaction()&amp;lt;/code&amp;gt; est le point d'idempotence.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeLogger&amp;lt;/code&amp;gt; || Écrit dans &amp;lt;code&amp;gt;llx_stripeaccounting_log&amp;lt;/code&amp;gt; et en miroir dans &amp;lt;code&amp;gt;dol_syslog()&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeAccounting&amp;lt;/code&amp;gt; || Construit les écritures (remboursement, litige, TVA autoliquidation) ou les mouvements bancaires (frais). Expose &amp;lt;code&amp;gt;checkConfig()&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripePayout&amp;lt;/code&amp;gt; || Crée le virement bancaire interne entre le compte Stripe et la banque réelle.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeSync&amp;lt;/code&amp;gt; || Orchestrateur : une méthode par flux, plus &amp;lt;code&amp;gt;reconcileStripeAccount()&amp;lt;/code&amp;gt; qui enchaîne tout.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeCsvImporter&amp;lt;/code&amp;gt; || Alimente le même pipeline depuis un export CSV Stripe.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ActionsStripeAccounting&amp;lt;/code&amp;gt; || Hook &amp;lt;code&amp;gt;bankcard&amp;lt;/code&amp;gt; : lien vers le tableau de bord sur la fiche du compte Stripe.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 4. Synchronisation et idempotence ==&lt;br /&gt;
&lt;br /&gt;
Chaque flux (&amp;lt;code&amp;gt;syncFees&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncRefunds&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncDisputes&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncPayouts&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncTransactions&amp;lt;/code&amp;gt;) suit toujours les mêmes étapes :&lt;br /&gt;
&lt;br /&gt;
# '''Vérifier la configuration''' — si elle est incomplète : log &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt;, arrêt immédiat, aucun appel API.&lt;br /&gt;
# '''Lister les objets Stripe''' sur une fenêtre glissante de '''35 jours'''.&lt;br /&gt;
# '''Filtrer''' — un objet est ignoré seulement s'il existe déjà ''et'' que son statut est &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;ignored&amp;lt;/code&amp;gt;. Une ligne en &amp;lt;code&amp;gt;pending&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; est '''retentée''' à ce run.&lt;br /&gt;
# '''Enregistrer''' en statut &amp;lt;code&amp;gt;pending&amp;lt;/code&amp;gt;, puis générer l'écriture ou le mouvement bancaire.&lt;br /&gt;
# '''Conclure''' — succès : statut &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt;. Échec : statut &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; avec le message, et '''le lot continue''' sur l'objet suivant.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #36c; background:#eaf3ff; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Reprise automatique''' — une ligne en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; redevient éligible au run suivant. Une fois la cause corrigée (par exemple un exercice comptable créé tardivement), aucune intervention manuelle n'est nécessaire.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi les doublons sont impossibles ===&lt;br /&gt;
&lt;br /&gt;
* '''Clé unique en base''' sur &amp;lt;code&amp;gt;(stripe_object_id, entity)&amp;lt;/code&amp;gt; — protège même contre deux exécutions concurrentes du cron.&lt;br /&gt;
* '''Test explicite avant traitement''' — évite jusqu'à la tentative d'écriture pour un objet déjà finalisé.&lt;br /&gt;
&lt;br /&gt;
=== Cas particuliers : &amp;lt;code&amp;gt;adjustment&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;payment_failure_refund&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Ce sont des corrections de solde effectuées par Stripe lui-même (réversion après litige, remboursement d'un paiement finalement échoué). Le module les '''enregistre''' — sinon elles resteraient invisibles — mais ne les comptabilise '''jamais''' automatiquement : le signe du montant et la cause varient trop. Elles sont créées directement en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, avec un message explicite, à traiter manuellement.&lt;br /&gt;
&lt;br /&gt;
== 5. Écritures comptables ==&lt;br /&gt;
&lt;br /&gt;
Toutes les lignes d'un même évènement partagent le triplet &amp;lt;code&amp;gt;doc_type='stripeaccounting'&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fk_doc&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;doc_ref&amp;lt;/code&amp;gt; : Dolibarr les regroupe automatiquement sous un même numéro de pièce, sans numérotation propre au module.&lt;br /&gt;
&lt;br /&gt;
=== Vue d'ensemble ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! Évènement !! Ce que fait le module !! Résultat comptable&lt;br /&gt;
|-&lt;br /&gt;
| Frais Stripe ''(TVA &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt;)'' || Mouvement bancaire &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; || Écriture 627xxx / 517xxx générée plus tard par Dolibarr&lt;br /&gt;
|-&lt;br /&gt;
| Frais Stripe ''(mode &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt;)'' || En plus : paire TVA postée immédiatement || Débit TVA déductible, crédit TVA autoliquidation ''(impact net nul)''&lt;br /&gt;
|-&lt;br /&gt;
| Frais Stripe ''(mode &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt;)'' || Écriture directe complète || Débit compte de frais HT + TVA déductible, crédit compte Stripe TTC&lt;br /&gt;
|-&lt;br /&gt;
| Frais d'abonnement / service ''(Radar, Billing, Connect…)'' || Mouvement bancaire &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; || Écriture générée plus tard par Dolibarr, sur le compte fournisseur Stripe&lt;br /&gt;
|-&lt;br /&gt;
| Virement (payout) || Virement bancaire interne entre les 2 comptes || Écriture générée plus tard par Dolibarr&lt;br /&gt;
|-&lt;br /&gt;
| Remboursement ''(facture retrouvée)'' || Écriture directe || Débit compte client 411xxx, crédit compte Stripe 517xxx&lt;br /&gt;
|-&lt;br /&gt;
| Remboursement ''(facture introuvable)'' || Rien || Statut &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, à traiter manuellement&lt;br /&gt;
|-&lt;br /&gt;
| Litige / chargeback || Écriture directe || Débit perte sur litiges 658xxx, crédit compte Stripe 517xxx ''(+ compte de frais si frais associés)''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi frais et virements ne génèrent pas d'écriture directe ===&lt;br /&gt;
&lt;br /&gt;
Le problème historique : quand une facture Stripe est transférée en comptabilité par le workflow standard de Dolibarr, le paiement est comptabilisé pour son montant '''brut''' — les frais sont ignorés à cette étape.&lt;br /&gt;
&lt;br /&gt;
Si le module postait ''en plus'' sa propre écriture ''et'' sa propre ligne bancaire, cette ligne resterait invisible pour &amp;lt;code&amp;gt;bankjournal.php&amp;lt;/code&amp;gt; — qui ne reconnaît que les lignes rattachées à &amp;lt;code&amp;gt;doc_type='bank'&amp;lt;/code&amp;gt;. Un administrateur transférant « normalement » le compte bancaire en comptabilité créait alors une '''seconde''' écriture pour le même mouvement.&lt;br /&gt;
&lt;br /&gt;
'''La solution retenue :''' pour les frais, les frais d'abonnement et les virements, le module ne crée plus que le '''mouvement bancaire réel''', avec les mécanismes natifs de Dolibarr. C'est ensuite le bouton natif ''« Transférer en comptabilité »'' qui produit l'écriture, comme pour n'importe quel autre mouvement bancaire. Le module ne touche donc plus du tout &amp;lt;code&amp;gt;llx_accounting_bookkeeping&amp;lt;/code&amp;gt; dans ces trois cas.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:22%;&amp;quot; | Cas !! Mécanisme natif utilisé&lt;br /&gt;
|-&lt;br /&gt;
| Frais et frais d'abonnement || &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; (mouvement bancaire avec compte de contrepartie, sans tiers ni facture), avec son propre &amp;lt;code&amp;gt;accountancy_code&amp;lt;/code&amp;gt; que &amp;lt;code&amp;gt;bankjournal.php&amp;lt;/code&amp;gt; lit directement.&lt;br /&gt;
|-&lt;br /&gt;
| Virements (payouts) || Virement interne Dolibarr : &amp;lt;code&amp;gt;Account::addline()&amp;lt;/code&amp;gt; des deux côtés, plus &amp;lt;code&amp;gt;add_url_line(…, 'banktransfert')&amp;lt;/code&amp;gt;. La contrepartie est imputée sur &amp;lt;code&amp;gt;ACCOUNTING_ACCOUNT_TRANSFER_CASH&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Dans les deux cas, le statut passe à &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt; — le module a fini son travail — mais '''&amp;lt;code&amp;gt;piece_num&amp;lt;/code&amp;gt; reste vide''' : l'écriture n'existe pas encore, seul &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; est renseigné. Après transfert manuel, on la retrouve avec &amp;lt;code&amp;gt;doc_type='bank'&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;fk_doc&amp;lt;/code&amp;gt; égal au &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; de la ligne.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #fc3; background:#fef6e7; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''À savoir''' — l'écriture des virements ne s'équilibre à zéro sur le compte de transfert que lorsque '''les deux''' comptes bancaires (Stripe ''et'' la banque réelle) ont été transférés en comptabilité, pas seulement un des deux.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #d33; background:#fee7e6; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''⚠ &amp;lt;code&amp;gt;STRIPE_AUTO_RECORD_PAYOUT&amp;lt;/code&amp;gt; doit rester désactivé'''&lt;br /&gt;
&lt;br /&gt;
Dès lors que ce module gère les virements, décochez « Activer l'enregistrement automatique des paiements Stripe » dans &amp;lt;code&amp;gt;stripe/admin/stripe.php&amp;lt;/code&amp;gt; — malgré son libellé, cette case ne concerne que les virements.&lt;br /&gt;
&lt;br /&gt;
Sinon, le webhook du module officiel et ce module créeraient chacun leur propre mouvement bancaire pour le même virement, sans le savoir l'un de l'autre.&lt;br /&gt;
&lt;br /&gt;
Le webhook cœur ne conserve d'ailleurs '''aucune''' trace de l'id du virement traité : en cas de double livraison Stripe (garantie « au moins une fois »), rien ne l'empêche de doublonner tout seul. Ce module, lui, a une vraie idempotence et rattrape automatiquement tout virement manqué sur 35 jours.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Page « Transferts Stripe » masquée ===&lt;br /&gt;
&lt;br /&gt;
À l'activation, &amp;lt;code&amp;gt;modStripeAccounting::init()&amp;lt;/code&amp;gt; désactive l'entrée de menu &amp;lt;code&amp;gt;stripe/payout.php&amp;lt;/code&amp;gt; : cette page interroge l'API en direct sans rien enregistrer, et sa coexistence avec ce module ne créerait qu'une confusion sur ce qui fait foi pour les virements. &amp;lt;code&amp;gt;remove()&amp;lt;/code&amp;gt; restaure la condition d'origine. '''C'est la seule table du cœur que ce module modifie''' — délibéré, et documenté ici pour cette raison.&lt;br /&gt;
&lt;br /&gt;
=== Frais par transaction ou frais d'abonnement ? ===&lt;br /&gt;
&lt;br /&gt;
Stripe facture deux choses distinctes sous le mot « frais » :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! !! Frais par transaction !! Frais d'abonnement / service&lt;br /&gt;
|-&lt;br /&gt;
! Exemple&lt;br /&gt;
| Commission sur chaque encaissement || Radar, Billing, Connect&lt;br /&gt;
|-&lt;br /&gt;
! Où le trouver&lt;br /&gt;
| Champ &amp;lt;code&amp;gt;.fee&amp;lt;/code&amp;gt; d'une balance transaction de type &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; || Balance transaction dédiée, de type &amp;lt;code&amp;gt;stripe_fee&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;application_fee&amp;lt;/code&amp;gt; ''(le &amp;lt;code&amp;gt;.fee&amp;lt;/code&amp;gt; y vaut toujours 0, le montant est dans &amp;lt;code&amp;gt;.amount&amp;lt;/code&amp;gt;)''&lt;br /&gt;
|-&lt;br /&gt;
! Compte utilisé&lt;br /&gt;
| Compte de frais configuré (627xxx) || Code comptable fournisseur du tiers Stripe configuré&lt;br /&gt;
|-&lt;br /&gt;
! Type en base&lt;br /&gt;
| &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Limite du mode TVA &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Ce mode doit scinder le montant TTC en HT + TVA, un découpage que &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; ne sait pas exprimer. Il reste donc sur l'ancien comportement : écriture directe complète, aucun mouvement bancaire créé. Pas de risque de doublon (puisque aucune ligne bancaire n'est produite), mais le solde &amp;lt;code&amp;gt;llx_bank&amp;lt;/code&amp;gt; du compte Stripe ne reflétera jamais les frais tant que ce mode est actif.&lt;br /&gt;
&lt;br /&gt;
== 6. Import CSV ==&lt;br /&gt;
&lt;br /&gt;
L'import couvre le cas d'un compte Stripe '''différent''' de celui configuré dans le module officiel — par exemple une autre boutique PrestaShop avec son propre compte marchand. L'API n'y a pas accès : le contenu est exporté en CSV depuis le dashboard Stripe, puis importé.&lt;br /&gt;
&lt;br /&gt;
=== Hypothèse de départ ===&lt;br /&gt;
&lt;br /&gt;
Les factures et paiements de cette boutique sont '''déjà''' comptabilisés dans Dolibarr par un autre processus, et l'encaissement (débit 517, crédit 411) est déjà posé. Seuls manquent les '''frais''', les '''remboursements''' et les '''virements''' — c'est exactement ce que l'import traite.&lt;br /&gt;
&lt;br /&gt;
=== Interface : un seul champ ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;import.php&amp;lt;/code&amp;gt; n'expose plus qu'un champ d'upload, '''Historique général''', câblé sur &amp;lt;code&amp;gt;importGeneralHistory()&amp;lt;/code&amp;gt;. Ce fichier couvre à lui seul tous les types de mouvements.&lt;br /&gt;
&lt;br /&gt;
Les méthodes &amp;lt;code&amp;gt;importPayments()&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;importPayouts()&amp;lt;/code&amp;gt; restent implémentées et fonctionnelles, mais ne sont plus atteignables depuis l'interface ; elles sont documentées ci-dessous pour mémoire.&lt;br /&gt;
&lt;br /&gt;
Comme le bouton « Synchroniser maintenant », l'import est bloqué — bandeau d'alerte, bouton désactivé, garde-fou côté serveur — tant que la configuration est incomplète.&lt;br /&gt;
&lt;br /&gt;
=== Les trois méthodes ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:24%;&amp;quot; | Méthode !! Export Stripe lu !! Traitement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;importGeneralHistory()&amp;lt;/code&amp;gt;&amp;lt;br /&amp;gt;''(seule exposée)'' || Balance history || Aiguillage par colonne &amp;lt;code&amp;gt;Type&amp;lt;/code&amp;gt;, voir tableau ci-dessous&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;importPayments()&amp;lt;/code&amp;gt; || Payments || Frais → écriture de frais. Montant remboursé → ligne &amp;lt;code&amp;gt;refund&amp;lt;/code&amp;gt; toujours en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;importPayouts()&amp;lt;/code&amp;gt; || Payouts || Exactement le même traitement qu'un payout venu de l'API&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Aiguillage de l'historique général, par colonne &amp;lt;code&amp;gt;Type&amp;lt;/code&amp;gt; :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:30%;&amp;quot; | Type Stripe !! Traitement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt; || Virement bancaire interne, comme via l'API&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;payment&amp;lt;/code&amp;gt; avec frais || Mouvement de frais&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_fee&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;application_fee&amp;lt;/code&amp;gt; || Frais d'abonnement, sur le compte fournisseur Stripe&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;refund&amp;lt;/code&amp;gt; || Enregistré, '''toujours''' en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;payout_minimum_balance_hold&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;…_release&amp;lt;/code&amp;gt; || '''Ignorés''' — réserve glissante Stripe, impact net nul, rien à comptabiliser&lt;br /&gt;
|-&lt;br /&gt;
| tout autre type || Enregistré en &amp;lt;code&amp;gt;type='other'&amp;lt;/code&amp;gt;, statut &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, type brut conservé dans la description. Aucune écriture devinée.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les colonnes sont reconnues '''par leur nom''' : l'ordre importe peu, et les colonnes en plus non utilisées sont ignorées.&lt;br /&gt;
&lt;br /&gt;
=== Idempotence de l'import ===&lt;br /&gt;
&lt;br /&gt;
La clé unique protège contre tout double import : réimporter le même CSV, ou un CSV qui chevauche un import précédent, ne crée aucun doublon.&lt;br /&gt;
&lt;br /&gt;
Point important : dans l'historique général, les lignes &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;payment&amp;lt;/code&amp;gt; sont indexées par leur colonne '''&amp;lt;code&amp;gt;Source&amp;lt;/code&amp;gt;''' (&amp;lt;code&amp;gt;po_…&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ch_…&amp;lt;/code&amp;gt;), pas par l'&amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt; de la ligne (&amp;lt;code&amp;gt;txn_…&amp;lt;/code&amp;gt;) — soit exactement la même clé que les imports dédiés. Importer l'historique général '''en plus''' des exports spécifiques ne poste donc jamais deux fois la même écriture, quel que soit l'ordre.&lt;br /&gt;
&lt;br /&gt;
Les identifiants Stripe étant uniques à l'échelle de la plateforme, mélanger dans la même table des lignes venant du compte API et de plusieurs comptes importés en CSV ne présente aucun risque de collision.&lt;br /&gt;
&lt;br /&gt;
=== Détails pratiques ===&lt;br /&gt;
&lt;br /&gt;
* '''Libellé source''' — un champ libre saisi à l'import (ex. « Boutique DRM ») est stocké sur chaque ligne créée et sert de colonne et de filtre dans la liste, pour distinguer plusieurs boutiques côte à côte.&lt;br /&gt;
* '''Format des montants''' — les CSV Stripe utilisent la virgule décimale française, convertie via &amp;lt;code&amp;gt;price2num()&amp;lt;/code&amp;gt;. Les dates marquées &amp;lt;code&amp;gt;(UTC)&amp;lt;/code&amp;gt; sont interprétées comme telles.&lt;br /&gt;
&lt;br /&gt;
== 7. Configuration ==&lt;br /&gt;
&lt;br /&gt;
La clé API et le mode test/live ne sont '''pas''' ressaisis ici : ils sont lus en lecture seule depuis le module Stripe officiel.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:26%;&amp;quot; | Champ !! Constante !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| Compte financier Stripe || &amp;lt;code&amp;gt;STRIPE_BANK_ACCOUNT_FOR_PAYMENTS&amp;lt;/code&amp;gt; ''(constante du module officiel)'' || Sélecteur de compte bancaire. Aucune copie locale, donc aucun risque de divergence.&lt;br /&gt;
|-&lt;br /&gt;
| Compte bancaire principal || &amp;lt;code&amp;gt;STRIPE_BANK_ACCOUNT_FOR_BANKTRANSFERS&amp;lt;/code&amp;gt; ''(constante du module officiel)'' || Même sélecteur. Voir l'encadré ci-dessous.&lt;br /&gt;
|-&lt;br /&gt;
| Compte de frais || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_FRAIS&amp;lt;/code&amp;gt; || Numéro de compte, ex. 627xxx&lt;br /&gt;
|-&lt;br /&gt;
| Compte de litiges || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_LITIGES&amp;lt;/code&amp;gt; || Numéro de compte, ex. 658xxx. '''Requis''' — utilisé dès qu'un litige survient, quel que soit le mode TVA.&lt;br /&gt;
|-&lt;br /&gt;
| Tiers fournisseur Stripe || &amp;lt;code&amp;gt;STRIPEACCOUNTING_FOURNISSEUR_STRIPE_ID&amp;lt;/code&amp;gt; || Tiers marqué fournisseur ; c'est son code comptable fournisseur qui est utilisé. Optionnel, sauf s'il existe des frais d'abonnement.&lt;br /&gt;
|-&lt;br /&gt;
| Mode TVA || &amp;lt;code&amp;gt;STRIPEACCOUNTING_VAT_MODE&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Compte TVA déductible (intracommunautaire) || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_TVA_DEDUCTIBLE&amp;lt;/code&amp;gt; || Requis si mode TVA ≠ &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt;. Stripe facturant toujours depuis une entité UE non française, la TVA déductible est intracommunautaire dans tous les cas.&lt;br /&gt;
|-&lt;br /&gt;
| Compte de TVA due (intracommunautaire) || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_TVA_AUTOLIQUIDATION&amp;lt;/code&amp;gt; || Requis en mode &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt; uniquement — jamais utilisé en mode &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| Taux de TVA || &amp;lt;code&amp;gt;STRIPEACCOUNTING_VAT_RATE&amp;lt;/code&amp;gt; || Pourcentage, 20 par défaut&lt;br /&gt;
|-&lt;br /&gt;
| Fréquence de synchronisation || &amp;lt;code&amp;gt;STRIPEACCOUNTING_SYNC_UNITFREQUENCY&amp;lt;/code&amp;gt; || Répercutée sur la tâche planifiée (en secondes)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #36c; background:#eaf3ff; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Pourquoi redéfinir le compte bancaire principal ici ?'''&lt;br /&gt;
&lt;br /&gt;
La page de configuration du module Stripe officiel n'affiche ce champ que si &amp;lt;code&amp;gt;STRIPE_AUTO_RECORD_PAYOUT&amp;lt;/code&amp;gt; est activé — et son handler de sauvegarde remet la valeur à 0 à chaque enregistrement tant que le champ n'est pas rendu. Or ce réglage doit justement rester désactivé quand ce module gère les virements. Le champ est donc réexposé ici, en écrivant directement la constante du cœur, pour que la valeur reste configurable et stable.&lt;br /&gt;
&lt;br /&gt;
Les deux sélecteurs de compte n'écrivent leur constante que si un compte réel a été soumis : enregistrer la page pour un tout autre champ n'écrase jamais une valeur correcte.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Vérification de la configuration ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;StripeAccounting::checkConfig()&amp;lt;/code&amp;gt; renvoie la liste des constantes manquantes. Elle est appelée à la fois par la page de configuration (bandeau d'information) et par chaque point d'entrée de synchronisation (garde-fou réel qui bloque tout traitement).&lt;br /&gt;
&lt;br /&gt;
=== Piège des sélecteurs de compte comptable ===&lt;br /&gt;
&lt;br /&gt;
Les quatre champs utilisant &amp;lt;code&amp;gt;FormAccounting::select_account()&amp;lt;/code&amp;gt; (frais, litiges, les deux comptes TVA) ont une option « rien sélectionné » dont la valeur est '''&amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;''' — une chaîne non vide, donc vraie en PHP. Un champ laissé vide et enregistré stocke littéralement &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;StripeAccounting::getAccountConst()&amp;lt;/code&amp;gt; normalise cette valeur en chaîne vide à la lecture, partout où ces constantes sont lues. Aucune écriture ne peut donc atterrir sur le compte inexistant &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 8. Interface ==&lt;br /&gt;
&lt;br /&gt;
=== Tableau de bord ===&lt;br /&gt;
&lt;br /&gt;
Solde Stripe (appel API en direct), nombre de transactions non rapprochées, total des frais du mois, payouts en attente, et bouton '''Synchroniser maintenant''' — désactivé, avec bandeau listant les constantes manquantes, tant que la configuration est incomplète.&lt;br /&gt;
&lt;br /&gt;
=== Liste des transactions ===&lt;br /&gt;
&lt;br /&gt;
Liste paginée, triable et filtrable, construite avec le même mécanisme que les listes natives Dolibarr : l'icône en haut à droite du tableau permet à chaque utilisateur de choisir ses colonnes, et la préférence est mémorisée par utilisateur.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:20%;&amp;quot; | Colonne !! Contenu&lt;br /&gt;
|-&lt;br /&gt;
| Montant, Frais, Total || Le popup sur les frais indique la TVA sur frais quand une paire d'autoliquidation ou une TVA française a été postée&lt;br /&gt;
|-&lt;br /&gt;
| Type, Description || Popup avec l'ID Stripe, l'ID d'évènement ou de source, et la description complète non tronquée&lt;br /&gt;
|-&lt;br /&gt;
| Tiers || Le client résolu via la facture, ou via la charge source pour son frais associé, ou le tiers fournisseur Stripe pour un frais d'abonnement&lt;br /&gt;
|-&lt;br /&gt;
| Écriture || Lien « Pièce n°X » vers l'écriture, et/ou lien vers le mouvement bancaire associé — voir la nuance ci-dessous&lt;br /&gt;
|-&lt;br /&gt;
| Source, Statut || Le badge &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; ouvre un popup avec le message d'erreur complet : plus besoin d'aller en base pour comprendre un échec&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #fc3; background:#fef6e7; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Lire la colonne « Écriture »''' — sur une ligne &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt;, le lien pointe vers le '''mouvement bancaire''', pas vers une pièce comptable. Le &amp;lt;code&amp;gt;piece_num&amp;lt;/code&amp;gt; du module, lui, n'est jamais l'écriture 627/517 du frais : c'est uniquement la paire TVA d'autoliquidation. L'écriture du frais est générée plus tard, par le bouton natif de Dolibarr, et n'est jamais reportée sur cette ligne.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La page est '''purement consultative''' : aucune comptabilisation manuelle n'y est proposée. Le module comptabilise automatiquement, et le transfert en comptabilité des frais et virements se fait depuis le bouton natif « Transférer en comptabilité ».&lt;br /&gt;
&lt;br /&gt;
=== Lignes &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Chaque paiement produit '''deux lignes''' en base :&lt;br /&gt;
&lt;br /&gt;
* une ligne &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt;, toujours en statut &amp;lt;code&amp;gt;ignored&amp;lt;/code&amp;gt;, frais à 0, jamais traitée — présente uniquement pour l'idempotence ;&lt;br /&gt;
* une ligne &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; pour le même paiement, liée à la première.&lt;br /&gt;
&lt;br /&gt;
Les deux apparaissent séparément dans la liste, mais la ligne &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; porte elle aussi le lien vers le paiement et la facture, résolu par jointure.&lt;br /&gt;
&lt;br /&gt;
=== Bandeau mode test ===&lt;br /&gt;
&lt;br /&gt;
Tant que le mode live n'est pas activé, le tableau de bord, la page de configuration et la liste des transactions affichent tous les trois le même avertissement que le module Stripe officiel. Impossible d'oublier qu'on travaille en mode test.&lt;br /&gt;
&lt;br /&gt;
=== Menus ===&lt;br /&gt;
&lt;br /&gt;
Tout est regroupé sous '''Banques et caisses → Compte Stripe''' (menu du module officiel), à plat, en trois entrées de même niveau :&lt;br /&gt;
&lt;br /&gt;
# Tableau de bord Stripe&lt;br /&gt;
# Transactions Stripe&lt;br /&gt;
# Import CSV ''(réservé aux administrateurs)''&lt;br /&gt;
&lt;br /&gt;
Un lien vers le tableau de bord est aussi ajouté automatiquement sur la fiche du compte bancaire configuré comme compte Stripe.&lt;br /&gt;
&lt;br /&gt;
== 9. Tâche planifiée ==&lt;br /&gt;
&lt;br /&gt;
Deux façons d'exécuter la synchronisation, toutes deux idempotentes et sans risque à relancer. Dans les deux cas le code exécuté est strictement le même : aucune divergence de comportement.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #d33; background:#fee7e6; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''⚠ Aucune des deux ne démarre toute seule.'''&lt;br /&gt;
&lt;br /&gt;
L'activation du module crée la tâche &amp;lt;code&amp;gt;StripeAccountingSync&amp;lt;/code&amp;gt;, mais '''désactivée par défaut'''. Et même activée, l'ordonnanceur Dolibarr n'est déclenché par rien tant qu'aucune crontab système ne l'appelle. Sans ces deux étapes, la synchro n'a lieu qu'au clic manuel sur « Synchroniser maintenant ».&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Étape 1 — activer la tâche ===&lt;br /&gt;
&lt;br /&gt;
Dans '''Accueil → Configuration → Modules → Tâches planifiées'''. &amp;lt;code&amp;gt;llx_cronjob&amp;lt;/code&amp;gt; étant une table du cœur, ce réglage se fait uniquement par l'interface, jamais en SQL direct depuis le module.&lt;br /&gt;
&lt;br /&gt;
=== Étape 2 — un déclencheur système ===&lt;br /&gt;
&lt;br /&gt;
Au choix, l'une des deux options.&lt;br /&gt;
&lt;br /&gt;
'''Option A — ordonnanceur Dolibarr''' ''(recommandé si plusieurs tâches planifiées coexistent)''. Lance toutes les tâches dues, pas seulement celle-ci. Nécessite l'étape 1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
*/15 * * * * curl &amp;quot;https://votre-dolibarr/public/cron/cron_run_jobs_by_url.php?securitykey=VOTRE_CLE&amp;amp;userlogin=VOTRE_LOGIN&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La clé de sécurité se génère sur la page des tâches planifiées, bouton « Sécurité de l'exécution des tâches par URL ».&lt;br /&gt;
&lt;br /&gt;
'''Option B — script CLI du module.''' Autonome, refuse l'exécution depuis un navigateur, et indépendant de l'état activé ou non de la tâche Dolibarr.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
*/15 * * * * php /chemin/vers/htdocs/custom/stripeaccounting/cron/stripe_sync.php &amp;gt;&amp;gt; /var/log/stripeaccounting.log 2&amp;gt;&amp;amp;1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 10. Journalisation et permissions ==&lt;br /&gt;
&lt;br /&gt;
=== Journalisation ===&lt;br /&gt;
&lt;br /&gt;
Chaque appel API, écriture générée, avertissement ou erreur est tracé dans &amp;lt;code&amp;gt;llx_stripeaccounting_log&amp;lt;/code&amp;gt;, consultable en base ou via le fichier de log standard Dolibarr. Niveaux : &amp;lt;code&amp;gt;DEBUG&amp;lt;/code&amp;gt; &amp;lt; &amp;lt;code&amp;gt;INFO&amp;lt;/code&amp;gt; &amp;lt; &amp;lt;code&amp;gt;WARNING&amp;lt;/code&amp;gt; &amp;lt; &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt;. La colonne &amp;lt;code&amp;gt;context&amp;lt;/code&amp;gt; contient le détail structuré en JSON (payload API, montants calculés…).&lt;br /&gt;
&lt;br /&gt;
=== Permissions ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Droit !! Contrôle&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;read&amp;lt;/code&amp;gt; || Consultation du tableau de bord et de la liste&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;write&amp;lt;/code&amp;gt; || Déclarée pour la configuration, mais non vérifiée dans le code aujourd'hui&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;reconcile&amp;lt;/code&amp;gt; || Déclenchement manuel de la synchronisation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
En pratique, &amp;lt;code&amp;gt;admin/setup.php&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;import.php&amp;lt;/code&amp;gt; ne contrôlent que le statut '''administrateur Dolibarr''', pas le droit &amp;lt;code&amp;gt;write&amp;lt;/code&amp;gt; : seuls les administrateurs peuvent configurer le module ou importer un CSV, quoi qu'il soit coché dans les permissions.&lt;br /&gt;
&lt;br /&gt;
== 11. Base de données ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;llx_stripeaccounting_transaction&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Une ligne par objet Stripe traité — charge, frais, remboursement, litige ou virement — tous dans la même table, distingués par la colonne &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:24%;&amp;quot; | Colonne !! style=&amp;quot;width:16%;&amp;quot; | Type !! Rôle&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rowid&amp;lt;/code&amp;gt; || int AI || Clé primaire&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;entity&amp;lt;/code&amp;gt; || int || Multi-société Dolibarr&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_object_id&amp;lt;/code&amp;gt; || varchar(80) || Identifiant Stripe — '''ancre d'idempotence'''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_event_id&amp;lt;/code&amp;gt; || varchar(80) || Identifiant d'évènement, informatif seulement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt; || varchar(20) || &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;refund&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;dispute&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;other&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_source_id&amp;lt;/code&amp;gt; || varchar(80) || Objet Stripe source (ex. la charge liée à un remboursement)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;source_label&amp;lt;/code&amp;gt; || varchar(80) || Libellé libre saisi à l'import CSV ; vide pour les lignes venues de l'API&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;description&amp;lt;/code&amp;gt; || varchar(255) || Libellé Stripe&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;amount&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;net&amp;lt;/code&amp;gt; || decimal(24,8) || Montants déjà convertis depuis les centimes Stripe&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;currency&amp;lt;/code&amp;gt; || varchar(3) || Code devise ISO&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;date_created&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;date_available_on&amp;lt;/code&amp;gt; || datetime || Dates côté Stripe&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_facture&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fk_paiement&amp;lt;/code&amp;gt; || int || Facture et paiement Dolibarr résolus, si trouvés&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; || int || Ligne &amp;lt;code&amp;gt;llx_bank&amp;lt;/code&amp;gt; générée ''(vide pour un frais en mode TVA &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt;)''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;piece_num&amp;lt;/code&amp;gt; || varchar(20) || Numéro de pièce comptable généré, quand il y en a un&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt; || varchar(16) || &amp;lt;code&amp;gt;pending&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ignored&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;error_message&amp;lt;/code&amp;gt; || text || Détail en cas d'erreur&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;date_creation&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;date_processed&amp;lt;/code&amp;gt; || datetime || Horodatage technique&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_user_creat&amp;lt;/code&amp;gt; || int || Utilisateur ayant déclenché le traitement&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Clé unique''' sur &amp;lt;code&amp;gt;(stripe_object_id, entity)&amp;lt;/code&amp;gt; — c'est elle qui garantit qu'un même objet Stripe ne peut jamais être inséré deux fois, même en cas d'exécutions concurrentes.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;llx_stripeaccounting_log&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Colonne !! Rôle&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;level&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;DEBUG&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;INFO&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;WARNING&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;message&amp;lt;/code&amp;gt; || Message court&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;context&amp;lt;/code&amp;gt; || Contexte structuré en JSON&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_stripeaccounting_transaction&amp;lt;/code&amp;gt; || Transaction liée, si applicable&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;datec&amp;lt;/code&amp;gt; || Horodatage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 12. Dépannage ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:26%;&amp;quot; | Symptôme !! Cause probable !! Action&lt;br /&gt;
|-&lt;br /&gt;
| Le bouton « Synchroniser maintenant » est désactivé || Configuration minimale incomplète || Compléter les champs listés dans le bandeau d'alerte de la page de configuration&lt;br /&gt;
|-&lt;br /&gt;
| Une transaction reste en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; || Écriture refusée par Dolibarr (compte inexistant, période clôturée), ou remboursement non rattaché || Lire &amp;lt;code&amp;gt;error_message&amp;lt;/code&amp;gt; sur la ligne, puis le détail dans la table de logs&lt;br /&gt;
|-&lt;br /&gt;
| Le solde Stripe ne s'affiche pas || Clé API manquante ou invalide dans le module Stripe officiel || Vérifier &amp;lt;code&amp;gt;stripe/admin/stripe.php&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Un remboursement n'est jamais rapproché || Le paiement d'origine n'a pas été retrouvé via &amp;lt;code&amp;gt;ext_payment_id&amp;lt;/code&amp;gt; || Vérifier que le paiement Stripe a bien été enregistré par le module officiel avec cet identifiant&lt;br /&gt;
|-&lt;br /&gt;
| Un &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt; reste en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; || Tiers fournisseur Stripe non renseigné, ou sans code comptable fournisseur || Renseigner le champ en configuration, et compléter la fiche du tiers&lt;br /&gt;
|-&lt;br /&gt;
| Un remboursement importé en CSV reste en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; || '''Normal et attendu''' — ce compte n'est pas relié à &amp;lt;code&amp;gt;ext_payment_id&amp;lt;/code&amp;gt; || Traiter la facture et le remboursement manuellement en comptabilité&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 13. Pièges rencontrés ==&lt;br /&gt;
&lt;br /&gt;
Notes de développement, conservées pour éviter de retomber dedans.&lt;br /&gt;
&lt;br /&gt;
* '''&amp;lt;code&amp;gt;PaymentVarious::create()&amp;lt;/code&amp;gt;''' ne met à jour &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; qu'en base, jamais sur l'objet PHP. Un &amp;lt;code&amp;gt;fetch()&amp;lt;/code&amp;gt; après &amp;lt;code&amp;gt;create()&amp;lt;/code&amp;gt; est indispensable pour récupérer la vraie valeur.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;select_comptes()&amp;lt;/code&amp;gt;''' affiche son propre HTML ''et'' retourne le nombre de comptes. L'appeler en instruction nue : l'envelopper dans &amp;lt;code&amp;gt;print&amp;lt;/code&amp;gt; réafficherait ce nombre juste après la balise select.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;master.inc.php&amp;lt;/code&amp;gt;, pas &amp;lt;code&amp;gt;main.inc.php&amp;lt;/code&amp;gt;''' pour le script CLI. Le second attend une session HTTP et, en pur CLI, se termine silencieusement — aucune sortie, aucun log, code retour 0 — dans sa redirection vers la page de connexion. L'impression trompeuse que le script « ne fait rien » plutôt qu'une vraie erreur.&lt;br /&gt;
* '''Bibliothèques du cœur''' — &amp;lt;code&amp;gt;master.inc.php&amp;lt;/code&amp;gt; ne charge pas tout ce que &amp;lt;code&amp;gt;main.inc.php&amp;lt;/code&amp;gt; charge pour le web (par exemple &amp;lt;code&amp;gt;core/lib/date.lib.php&amp;lt;/code&amp;gt;, requis par &amp;lt;code&amp;gt;BookKeeping&amp;lt;/code&amp;gt;). À inclure explicitement si le script CLI évolue.&lt;br /&gt;
* '''Option « rien sélectionné » à &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;''' dans les sélecteurs de compte comptable — voir la section Configuration.&lt;br /&gt;
&lt;br /&gt;
== 14. Limites connues ==&lt;br /&gt;
&lt;br /&gt;
* '''Devises « zéro décimale »''' (JPY, KRW…) non gérées : les montants sont divisés par 100 en supposant deux décimales. Usage prévu : EUR.&lt;br /&gt;
* '''Fenêtre de 35 jours''' non configurable. Une synchronisation interrompue plus longtemps devra être rattrapée manuellement.&lt;br /&gt;
* '''Rattachement des remboursements''' — dépend de &amp;lt;code&amp;gt;ext_payment_id&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;ext_payment_site&amp;lt;/code&amp;gt; sur &amp;lt;code&amp;gt;llx_paiement&amp;lt;/code&amp;gt;, renseignés par le flux de paiement Stripe standard. Un paiement enregistré autrement ne pourra pas être rattaché automatiquement. Le rattachement se fait via le '''PaymentIntent id''', jamais via l'id de charge : le module Stripe du cœur ne stocke jamais ce dernier ''(il y met soit le PaymentIntent brut, soit un composite, selon le chemin de paiement emprunté)''.&lt;br /&gt;
* '''Import CSV en notation française''' uniquement : un export à point décimal ne serait pas interprété correctement.&lt;br /&gt;
* '''Colonne « Transfer » du CSV Paiements''' stockée à titre informatif seulement : elle ne sert pas à vérifier que le total des paiements correspond au montant du virement importé.&lt;br /&gt;
* '''Remboursements importés en CSV toujours en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;''' — comportement voulu, pas un bug.&lt;br /&gt;
* '''Mode TVA &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt;''' — le solde bancaire du compte Stripe ne reflète pas les frais, voir section 5.&lt;br /&gt;
&lt;br /&gt;
[[Catégorie:Dolibarr]]&lt;br /&gt;
[[Catégorie:Modules]]&lt;br /&gt;
[[Catégorie:Comptabilité]]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Stripeaccounting/en&amp;diff=553</id>
		<title>Stripeaccounting/en</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Stripeaccounting/en&amp;diff=553"/>
				<updated>2026-08-02T12:41:00Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:StripeAccounting — Technical documentation}}&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Fr.png|32px|link=Stripeaccounting|Doc en Français]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border:1px solid #c8ccd1; background:#f8f9fa; border-radius:4px; padding:1em 1.2em; margin:0 0 1.5em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''StripeAccounting''' is a Dolibarr module for '''Stripe accounting reconciliation'''.&lt;br /&gt;
&lt;br /&gt;
It reads the Stripe API (or a CSV export), identifies the movements the official Stripe module does not post — fees, refunds, disputes, payouts — and creates the missing accounting entries.&lt;br /&gt;
&lt;br /&gt;
: '''Compatibility''' — Dolibarr 17+, PHP 7.2 → 8.5&lt;br /&gt;
: '''Depends on''' — Stripe, Bank and Double-entry Accounting modules&lt;br /&gt;
: '''See also''' — [[README|Installation and user guide]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== 1. Design principles ==&lt;br /&gt;
&lt;br /&gt;
Four rules govern the whole module.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:22%;&amp;quot; | Principle !! What it means&lt;br /&gt;
|-&lt;br /&gt;
| '''Complementary''' || The module creates no payment, no invoice, no webhook. It reads Stripe and completes the books, nothing more.&lt;br /&gt;
|-&lt;br /&gt;
| '''Idempotent''' || Each Stripe object is processed once only, no matter how many times the sync is re-run.&lt;br /&gt;
|-&lt;br /&gt;
| '''Never guess''' || If an operation cannot be matched with certainty, nothing is posted: the row goes to &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; for manual review.&lt;br /&gt;
|-&lt;br /&gt;
| '''Configuration is blocking''' || As long as the minimum configuration is incomplete, no sync runs at all (no button, no cron, no import).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2. Requirements ==&lt;br /&gt;
&lt;br /&gt;
=== Required Dolibarr modules ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Module !! What it provides&lt;br /&gt;
|-&lt;br /&gt;
| '''Stripe''' (&amp;lt;code&amp;gt;modStripe&amp;lt;/code&amp;gt;) || API key, test/live mode, Stripe financial account&lt;br /&gt;
|-&lt;br /&gt;
| '''Bank''' (&amp;lt;code&amp;gt;modBanque&amp;lt;/code&amp;gt;) || &amp;lt;code&amp;gt;llx_bank&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;llx_bank_account&amp;lt;/code&amp;gt; tables&lt;br /&gt;
|-&lt;br /&gt;
| '''Double-entry accounting''' (&amp;lt;code&amp;gt;modAccounting&amp;lt;/code&amp;gt;) || &amp;lt;code&amp;gt;llx_accounting_bookkeeping&amp;lt;/code&amp;gt; table&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Mandatory Dolibarr setting ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ACCOUNTING_ACCOUNT_TRANSFER_CASH&amp;lt;/code&amp;gt; must be set under '''Accounting → Setup → Miscellaneous accounts'''. Without it, the internal transfer generated by payouts cannot be transferred to accounting (a Dolibarr limitation, not a module one).&lt;br /&gt;
&lt;br /&gt;
=== Notes ===&lt;br /&gt;
&lt;br /&gt;
* The Stripe PHP SDK is not re-vendored: the module reuses the core copy (&amp;lt;code&amp;gt;includes/stripe/stripe-php/&amp;lt;/code&amp;gt;).&lt;br /&gt;
* The code deliberately avoids any PHP syntax newer than 7.2 (no &amp;lt;code&amp;gt;match&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;?-&amp;gt;&amp;lt;/code&amp;gt;, enums, typed properties, &amp;lt;code&amp;gt;str_contains&amp;lt;/code&amp;gt;…) so it runs across the whole 7.2 → 8.5 range.&lt;br /&gt;
&lt;br /&gt;
== 3. File tree ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
custom/stripeaccounting/&lt;br /&gt;
├── core/modules/modStripeAccounting.class.php   Module descriptor (permissions, menus, cron, constants)&lt;br /&gt;
├── class/&lt;br /&gt;
│   ├── StripeApi.class.php                      Stripe SDK wrapper (read-only)&lt;br /&gt;
│   ├── StripeRepository.class.php               SQL access + idempotency&lt;br /&gt;
│   ├── StripeLogger.class.php                   Logging&lt;br /&gt;
│   ├── StripeAccounting.class.php               Accounting entry generation&lt;br /&gt;
│   ├── StripePayout.class.php                   Payout reconciliation&lt;br /&gt;
│   ├── StripeSync.class.php                     Orchestrator (cron entry point)&lt;br /&gt;
│   ├── StripeCsvImporter.class.php              CSV import&lt;br /&gt;
│   └── actions_stripeaccounting.class.php       'bankcard' hook&lt;br /&gt;
├── admin/setup.php                              Configuration&lt;br /&gt;
├── import.php                                   CSV import&lt;br /&gt;
├── dashboard.php                                Dashboard&lt;br /&gt;
├── transaction_list.php                         Transaction list&lt;br /&gt;
├── cron/stripe_sync.php                         CLI entry point&lt;br /&gt;
├── lib/stripeaccounting.lib.php&lt;br /&gt;
├── sql/&lt;br /&gt;
├── langs/{fr_FR,en_US,es_ES,it_IT,de_DE}/&lt;br /&gt;
└── css/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dependency direction ===&lt;br /&gt;
&lt;br /&gt;
: pages and hook → &amp;lt;code&amp;gt;StripeSync&amp;lt;/code&amp;gt; → (&amp;lt;code&amp;gt;StripeApi&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StripeRepository&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StripeAccounting&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StripePayout&amp;lt;/code&amp;gt;) → &amp;lt;code&amp;gt;StripeLogger&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:26%;&amp;quot; | Class !! Role&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeApi&amp;lt;/code&amp;gt; || Queries the Stripe SDK (balance transactions, charges, refunds, disputes, payouts) with automatic pagination. No database access, no accounting entries.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeRepository&amp;lt;/code&amp;gt; || All SQL for the module's two tables. &amp;lt;code&amp;gt;upsertTransaction()&amp;lt;/code&amp;gt; is the idempotency anchor.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeLogger&amp;lt;/code&amp;gt; || Writes to &amp;lt;code&amp;gt;llx_stripeaccounting_log&amp;lt;/code&amp;gt; and mirrors to &amp;lt;code&amp;gt;dol_syslog()&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeAccounting&amp;lt;/code&amp;gt; || Builds accounting entries (refund, dispute, reverse-charge VAT) or bank movements (fees). Exposes &amp;lt;code&amp;gt;checkConfig()&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripePayout&amp;lt;/code&amp;gt; || Creates the internal bank transfer between the Stripe account and the real bank account.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeSync&amp;lt;/code&amp;gt; || Orchestrator: one method per flow, plus &amp;lt;code&amp;gt;reconcileStripeAccount()&amp;lt;/code&amp;gt; which chains them all.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeCsvImporter&amp;lt;/code&amp;gt; || Feeds the same pipeline from a Stripe CSV export.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ActionsStripeAccounting&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;bankcard&amp;lt;/code&amp;gt; hook: dashboard link on the Stripe account record.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 4. Synchronisation and idempotency ==&lt;br /&gt;
&lt;br /&gt;
Every flow (&amp;lt;code&amp;gt;syncFees&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncRefunds&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncDisputes&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncPayouts&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncTransactions&amp;lt;/code&amp;gt;) always follows the same steps:&lt;br /&gt;
&lt;br /&gt;
# '''Check the configuration''' — if incomplete: &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt; log, immediate stop, no API call at all.&lt;br /&gt;
# '''List Stripe objects''' over a rolling window of '''35 days'''.&lt;br /&gt;
# '''Filter''' — an object is skipped only if it already exists ''and'' its status is &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;ignored&amp;lt;/code&amp;gt;. A row in &amp;lt;code&amp;gt;pending&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; is '''retried''' on this run.&lt;br /&gt;
# '''Record''' it as &amp;lt;code&amp;gt;pending&amp;lt;/code&amp;gt;, then generate the accounting entry or bank movement.&lt;br /&gt;
# '''Conclude''' — success: status &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt;. Failure: status &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; with the message, and '''the batch carries on''' with the next object.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #36c; background:#eaf3ff; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Automatic retry''' — a row in &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; becomes eligible again on the next run. Once the cause is fixed (a fiscal year created late, for instance), no manual action is needed.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Why duplicates are impossible ===&lt;br /&gt;
&lt;br /&gt;
* '''Unique database key''' on &amp;lt;code&amp;gt;(stripe_object_id, entity)&amp;lt;/code&amp;gt; — protects even against two concurrent cron executions.&lt;br /&gt;
* '''Explicit check before processing''' — avoids even attempting to post an entry for an already-finalised object.&lt;br /&gt;
&lt;br /&gt;
=== Special cases: &amp;lt;code&amp;gt;adjustment&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;payment_failure_refund&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
These are balance corrections Stripe makes on its own (reversal after a dispute is resolved, automatic refund of a payment that ultimately failed). The module '''records''' them — otherwise they would stay invisible — but '''never''' posts them automatically: the sign of the amount and the underlying cause vary too much. They are created directly in &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, with an explicit message, to be handled manually.&lt;br /&gt;
&lt;br /&gt;
== 5. Accounting entries ==&lt;br /&gt;
&lt;br /&gt;
All lines of a single Stripe event share the same &amp;lt;code&amp;gt;doc_type='stripeaccounting'&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fk_doc&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;doc_ref&amp;lt;/code&amp;gt; triplet: Dolibarr automatically groups them under one piece number, so the module needs no numbering scheme of its own.&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! Event !! What the module does !! Resulting entry&lt;br /&gt;
|-&lt;br /&gt;
| Stripe fee ''(VAT mode &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt;)'' || &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; bank movement || 627xxx / 517xxx entry generated later by Dolibarr&lt;br /&gt;
|-&lt;br /&gt;
| Stripe fee ''(&amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt; mode)'' || Plus: VAT pair posted immediately || Debit deductible VAT, credit reverse-charge VAT ''(net impact nil)''&lt;br /&gt;
|-&lt;br /&gt;
| Stripe fee ''(&amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; mode)'' || Full direct entry || Debit fee account excl. VAT + deductible VAT, credit Stripe account incl. VAT&lt;br /&gt;
|-&lt;br /&gt;
| Subscription / service fees ''(Radar, Billing, Connect…)'' || &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; bank movement || Entry generated later by Dolibarr, on the Stripe supplier account&lt;br /&gt;
|-&lt;br /&gt;
| Payout || Internal bank transfer between the two accounts || Entry generated later by Dolibarr&lt;br /&gt;
|-&lt;br /&gt;
| Refund ''(invoice found)'' || Direct entry || Debit customer account 411xxx, credit Stripe account 517xxx&lt;br /&gt;
|-&lt;br /&gt;
| Refund ''(invoice not found)'' || Nothing || Status &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, handle manually&lt;br /&gt;
|-&lt;br /&gt;
| Dispute / chargeback || Direct entry || Debit dispute loss 658xxx, credit Stripe account 517xxx ''(+ fee account if fees apply)''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Why fees and payouts produce no direct entry ===&lt;br /&gt;
&lt;br /&gt;
The historical problem: when a Stripe-paid invoice is transferred to accounting through Dolibarr's standard workflow, the payment is posted at its '''gross''' amount — fees are ignored at that stage.&lt;br /&gt;
&lt;br /&gt;
If the module posted its own entry ''and'' its own bank line on top of that, this line would stay invisible to &amp;lt;code&amp;gt;bankjournal.php&amp;lt;/code&amp;gt; — which only recognises lines attached to &amp;lt;code&amp;gt;doc_type='bank'&amp;lt;/code&amp;gt;. An administrator transferring the bank account to accounting &amp;quot;normally&amp;quot; would then create a '''second''' entry for the very same movement.&lt;br /&gt;
&lt;br /&gt;
'''The chosen solution:''' for fees, subscription fees and payouts, the module now creates only the '''real bank movement''', using Dolibarr's native mechanisms. The native ''&amp;quot;Transfer to accounting&amp;quot;'' button then produces the entry, exactly as for any other bank movement. In those three cases, the module no longer touches &amp;lt;code&amp;gt;llx_accounting_bookkeeping&amp;lt;/code&amp;gt; at all.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:22%;&amp;quot; | Case !! Native mechanism used&lt;br /&gt;
|-&lt;br /&gt;
| Fees and subscription fees || &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; (bank movement with an explicit counterpart account, no third party or invoice), carrying its own &amp;lt;code&amp;gt;accountancy_code&amp;lt;/code&amp;gt;, which &amp;lt;code&amp;gt;bankjournal.php&amp;lt;/code&amp;gt; reads directly.&lt;br /&gt;
|-&lt;br /&gt;
| Payouts || Dolibarr internal transfer: &amp;lt;code&amp;gt;Account::addline()&amp;lt;/code&amp;gt; on both sides, plus &amp;lt;code&amp;gt;add_url_line(…, 'banktransfert')&amp;lt;/code&amp;gt;. The counterpart is posted to &amp;lt;code&amp;gt;ACCOUNTING_ACCOUNT_TRANSFER_CASH&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In both cases the status becomes &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt; — the module's job is done — but '''&amp;lt;code&amp;gt;piece_num&amp;lt;/code&amp;gt; stays empty''': the entry does not exist yet, only &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; is set. After the manual transfer, it can be found with &amp;lt;code&amp;gt;doc_type='bank'&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;fk_doc&amp;lt;/code&amp;gt; equal to the row's &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #fc3; background:#fef6e7; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Worth knowing''' — the payout entry only balances to zero on the transfer account once '''both''' bank accounts (Stripe ''and'' the real bank) have been transferred to accounting, not just one of them.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #d33; background:#fee7e6; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''⚠ &amp;lt;code&amp;gt;STRIPE_AUTO_RECORD_PAYOUT&amp;lt;/code&amp;gt; must stay disabled'''&lt;br /&gt;
&lt;br /&gt;
Once this module handles payouts, untick &amp;quot;Enable automatic recording of Stripe payments&amp;quot; in &amp;lt;code&amp;gt;stripe/admin/stripe.php&amp;lt;/code&amp;gt; — despite its wording, that checkbox only concerns payouts.&lt;br /&gt;
&lt;br /&gt;
Otherwise the official module's webhook and this module would each create their own bank movement for the same payout, unaware of each other.&lt;br /&gt;
&lt;br /&gt;
The core webhook keeps '''no''' trace of the payout id it has processed: should Stripe deliver the event twice (delivery is guaranteed &amp;quot;at least once&amp;quot;), nothing stops it from duplicating on its own either. This module has real idempotency and automatically catches up any missed payout within 35 days.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The &amp;quot;Stripe transfers&amp;quot; page is hidden ===&lt;br /&gt;
&lt;br /&gt;
On activation, &amp;lt;code&amp;gt;modStripeAccounting::init()&amp;lt;/code&amp;gt; disables the &amp;lt;code&amp;gt;stripe/payout.php&amp;lt;/code&amp;gt; menu entry: that page queries the API live without recording anything, and having it alongside this module would only create confusion about which one is authoritative for payouts. &amp;lt;code&amp;gt;remove()&amp;lt;/code&amp;gt; restores the original condition. '''This is the only core table the module modifies''' — deliberate, and documented here for that reason.&lt;br /&gt;
&lt;br /&gt;
=== Per-transaction fees or subscription fees? ===&lt;br /&gt;
&lt;br /&gt;
Stripe bills two distinct things under the generic word &amp;quot;fees&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! !! Per-transaction fees !! Subscription / service fees&lt;br /&gt;
|-&lt;br /&gt;
! Example&lt;br /&gt;
| Commission on each payment || Radar, Billing, Connect&lt;br /&gt;
|-&lt;br /&gt;
! Where to find it&lt;br /&gt;
| The &amp;lt;code&amp;gt;.fee&amp;lt;/code&amp;gt; field of a &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; balance transaction || A dedicated balance transaction, type &amp;lt;code&amp;gt;stripe_fee&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;application_fee&amp;lt;/code&amp;gt; ''(its &amp;lt;code&amp;gt;.fee&amp;lt;/code&amp;gt; is always 0, the amount sits in &amp;lt;code&amp;gt;.amount&amp;lt;/code&amp;gt;)''&lt;br /&gt;
|-&lt;br /&gt;
! Account used&lt;br /&gt;
| The configured fee account (627xxx) || The supplier accounting code of the configured Stripe third party&lt;br /&gt;
|-&lt;br /&gt;
! Type in database&lt;br /&gt;
| &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Limitation of the &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; VAT mode ===&lt;br /&gt;
&lt;br /&gt;
This mode has to split the gross amount into net + VAT, something &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; cannot express. It therefore keeps the previous behaviour: a full direct entry, with no bank movement created. No duplicate risk (precisely because no bank line is produced), but the &amp;lt;code&amp;gt;llx_bank&amp;lt;/code&amp;gt; balance of the Stripe account will never reflect the fees while this mode is active.&lt;br /&gt;
&lt;br /&gt;
== 6. CSV import ==&lt;br /&gt;
&lt;br /&gt;
The import covers the case of a Stripe account '''different''' from the one configured in the official module — another PrestaShop shop with its own merchant account, for example. The API has no access to it: its contents are exported to CSV from the Stripe dashboard, then imported.&lt;br /&gt;
&lt;br /&gt;
=== Starting assumption ===&lt;br /&gt;
&lt;br /&gt;
The invoices and payments of that shop are '''already''' posted in Dolibarr through some other process, and the collection (debit 517, credit 411) is already booked. Only the '''fees''', '''refunds''' and '''payouts''' are missing — which is exactly what the import handles.&lt;br /&gt;
&lt;br /&gt;
=== Interface: a single field ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;import.php&amp;lt;/code&amp;gt; now exposes only one upload field, '''General history''', wired to &amp;lt;code&amp;gt;importGeneralHistory()&amp;lt;/code&amp;gt;. That file alone covers every movement type.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;importPayments()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;importPayouts()&amp;lt;/code&amp;gt; are still implemented and functional, but no longer reachable from the interface; they are documented below for reference.&lt;br /&gt;
&lt;br /&gt;
Like the &amp;quot;Sync now&amp;quot; button, the import is blocked — warning banner, disabled button, server-side guard — while the configuration is incomplete.&lt;br /&gt;
&lt;br /&gt;
=== The three methods ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:24%;&amp;quot; | Method !! Stripe export read !! Processing&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;importGeneralHistory()&amp;lt;/code&amp;gt;&amp;lt;br /&amp;gt;''(the only one exposed)'' || Balance history || Dispatch on the &amp;lt;code&amp;gt;Type&amp;lt;/code&amp;gt; column, see table below&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;importPayments()&amp;lt;/code&amp;gt; || Payments || Fee → fee movement. Amount refunded → &amp;lt;code&amp;gt;refund&amp;lt;/code&amp;gt; row, always in &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;importPayouts()&amp;lt;/code&amp;gt; || Payouts || Exactly the same processing as a payout coming from the API&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
General history dispatch, by &amp;lt;code&amp;gt;Type&amp;lt;/code&amp;gt; column:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:30%;&amp;quot; | Stripe type !! Processing&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt; || Internal bank transfer, as via the API&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;payment&amp;lt;/code&amp;gt; with a fee || Fee movement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_fee&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;application_fee&amp;lt;/code&amp;gt; || Subscription fee, on the Stripe supplier account&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;refund&amp;lt;/code&amp;gt; || Recorded, '''always''' in &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;payout_minimum_balance_hold&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;…_release&amp;lt;/code&amp;gt; || '''Ignored''' — Stripe rolling reserve, no real cash movement, nothing to post&lt;br /&gt;
|-&lt;br /&gt;
| any other type || Recorded as &amp;lt;code&amp;gt;type='other'&amp;lt;/code&amp;gt;, status &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, raw Stripe type kept in the description. No guessed entry.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Columns are matched '''by name''': their order does not matter, and extra unused columns are ignored.&lt;br /&gt;
&lt;br /&gt;
=== Import idempotency ===&lt;br /&gt;
&lt;br /&gt;
The unique key protects against any double import: re-importing the same CSV, or one overlapping a previous import, creates no duplicate.&lt;br /&gt;
&lt;br /&gt;
An important detail: in the general history, &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;payment&amp;lt;/code&amp;gt; rows are indexed by their '''&amp;lt;code&amp;gt;Source&amp;lt;/code&amp;gt;''' column (&amp;lt;code&amp;gt;po_…&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ch_…&amp;lt;/code&amp;gt;), not by the row's own &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;txn_…&amp;lt;/code&amp;gt;) — the very same key the dedicated imports use. Importing the general history '''on top of''' the specific exports therefore never posts the same entry twice, in any order.&lt;br /&gt;
&lt;br /&gt;
Since Stripe identifiers are unique platform-wide, mixing rows from the API account and from several CSV-imported accounts in the same table carries no collision risk.&lt;br /&gt;
&lt;br /&gt;
=== Practical details ===&lt;br /&gt;
&lt;br /&gt;
* '''Source label''' — a free-text field entered at import time (e.g. &amp;quot;DRM shop&amp;quot;) is stored on every created row and serves as a column and filter in the list, to tell several shops apart side by side.&lt;br /&gt;
* '''Amount format''' — Stripe CSVs use the French decimal comma, converted through &amp;lt;code&amp;gt;price2num()&amp;lt;/code&amp;gt;. Dates marked &amp;lt;code&amp;gt;(UTC)&amp;lt;/code&amp;gt; are interpreted as such.&lt;br /&gt;
&lt;br /&gt;
== 7. Configuration ==&lt;br /&gt;
&lt;br /&gt;
The API key and test/live mode are '''not''' re-entered here: they are read, read-only, from the official Stripe module.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:26%;&amp;quot; | Field !! Constant !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| Stripe financial account || &amp;lt;code&amp;gt;STRIPE_BANK_ACCOUNT_FOR_PAYMENTS&amp;lt;/code&amp;gt; ''(official module constant)'' || Bank account selector. No local copy, hence no risk of divergence.&lt;br /&gt;
|-&lt;br /&gt;
| Main bank account || &amp;lt;code&amp;gt;STRIPE_BANK_ACCOUNT_FOR_BANKTRANSFERS&amp;lt;/code&amp;gt; ''(official module constant)'' || Same selector. See the box below.&lt;br /&gt;
|-&lt;br /&gt;
| Fee account || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_FRAIS&amp;lt;/code&amp;gt; || Account number, e.g. 627xxx&lt;br /&gt;
|-&lt;br /&gt;
| Dispute account || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_LITIGES&amp;lt;/code&amp;gt; || Account number, e.g. 658xxx. '''Required''' — used as soon as a dispute occurs, whatever the VAT mode.&lt;br /&gt;
|-&lt;br /&gt;
| Stripe supplier third party || &amp;lt;code&amp;gt;STRIPEACCOUNTING_FOURNISSEUR_STRIPE_ID&amp;lt;/code&amp;gt; || A third party flagged as supplier; its supplier accounting code is what gets used. Optional, unless subscription fees exist.&lt;br /&gt;
|-&lt;br /&gt;
| VAT mode || &amp;lt;code&amp;gt;STRIPEACCOUNTING_VAT_MODE&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Deductible VAT account (intra-EU) || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_TVA_DEDUCTIBLE&amp;lt;/code&amp;gt; || Required when the VAT mode is not &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt;. Stripe always invoices from a non-French EU entity, so the deductible VAT is intra-EU in every case.&lt;br /&gt;
|-&lt;br /&gt;
| VAT due account (intra-EU) || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_TVA_AUTOLIQUIDATION&amp;lt;/code&amp;gt; || Required in &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt; mode only — never used in &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; mode.&lt;br /&gt;
|-&lt;br /&gt;
| VAT rate || &amp;lt;code&amp;gt;STRIPEACCOUNTING_VAT_RATE&amp;lt;/code&amp;gt; || Percentage, 20 by default&lt;br /&gt;
|-&lt;br /&gt;
| Sync frequency || &amp;lt;code&amp;gt;STRIPEACCOUNTING_SYNC_UNITFREQUENCY&amp;lt;/code&amp;gt; || Applied to the scheduled job (in seconds)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #36c; background:#eaf3ff; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Why redefine the main bank account here?'''&lt;br /&gt;
&lt;br /&gt;
The official Stripe module's setup page only renders that field when &amp;lt;code&amp;gt;STRIPE_AUTO_RECORD_PAYOUT&amp;lt;/code&amp;gt; is enabled — and its own save handler resets the value to 0 on every save while the field is not rendered. Yet that setting must stay disabled once this module handles payouts. The field is therefore re-exposed here, writing the core constant directly, so the value stays configurable and stable.&lt;br /&gt;
&lt;br /&gt;
Both account selectors only write their constant when a real account was submitted: saving the page for some unrelated field never overwrites a correct value.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Configuration check ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;StripeAccounting::checkConfig()&amp;lt;/code&amp;gt; returns the list of missing constants. It is called both by the setup page (information banner) and by every sync entry point (the real guard that blocks all processing).&lt;br /&gt;
&lt;br /&gt;
=== Pitfall with accounting account selectors ===&lt;br /&gt;
&lt;br /&gt;
The four fields using &amp;lt;code&amp;gt;FormAccounting::select_account()&amp;lt;/code&amp;gt; (fees, disputes, both VAT accounts) have a &amp;quot;nothing selected&amp;quot; option whose value is '''&amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;''' — a non-empty string, therefore truthy in PHP. A field left blank and saved literally stores &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;StripeAccounting::getAccountConst()&amp;lt;/code&amp;gt; normalises that value to an empty string on read, everywhere these constants are read. No entry can therefore land on the non-existent account &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 8. User interface ==&lt;br /&gt;
&lt;br /&gt;
=== Dashboard ===&lt;br /&gt;
&lt;br /&gt;
Stripe balance (live API call), number of unreconciled transactions, total fees for the month, pending payouts, and a '''Sync now''' button — disabled, with a banner listing the missing constants, while the configuration is incomplete.&lt;br /&gt;
&lt;br /&gt;
=== Transaction list ===&lt;br /&gt;
&lt;br /&gt;
A paginated, sortable, filterable list built with the same mechanism as native Dolibarr lists: the icon at the top right of the table lets each user pick their columns, and the preference is stored per user.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:20%;&amp;quot; | Column !! Content&lt;br /&gt;
|-&lt;br /&gt;
| Amount, Fee, Total || The fee popup shows the VAT on the fee whenever a reverse-charge pair or French VAT was posted&lt;br /&gt;
|-&lt;br /&gt;
| Type, Description || Popup with the Stripe ID, the event or source ID, and the full untruncated description&lt;br /&gt;
|-&lt;br /&gt;
| Third party || The customer resolved through the invoice, or through the source charge for its related fee, or the configured Stripe supplier for a subscription fee&lt;br /&gt;
|-&lt;br /&gt;
| Entry || A &amp;quot;Piece no. X&amp;quot; link to the accounting entry, and/or a link to the related bank movement — see the caveat below&lt;br /&gt;
|-&lt;br /&gt;
| Source, Status || The &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; badge opens a popup with the full error message: no need to query the database to understand a failure&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #fc3; background:#fef6e7; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Reading the &amp;quot;Entry&amp;quot; column''' — on a &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt; row, the link points to the '''bank movement''', not to an accounting piece. The module's &amp;lt;code&amp;gt;piece_num&amp;lt;/code&amp;gt; is never the 627/517 entry for the fee: it is only the reverse-charge VAT pair. The fee entry itself is generated later, by Dolibarr's native button, and is never reported back onto this row.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The page is '''purely informational''': no manual posting is offered there. The module posts automatically, and the actual transfer to accounting for fees and payouts happens through the native &amp;quot;Transfer to accounting&amp;quot; button.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; rows ===&lt;br /&gt;
&lt;br /&gt;
Each payment produces '''two rows''' in the database:&lt;br /&gt;
&lt;br /&gt;
* a &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; row, always in status &amp;lt;code&amp;gt;ignored&amp;lt;/code&amp;gt;, fee 0, never processed — present solely for idempotency;&lt;br /&gt;
* a &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; row for the same payment, linked to the first one.&lt;br /&gt;
&lt;br /&gt;
Both appear separately in the list, but the &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; row also carries the link to the payment and the invoice, resolved through a join.&lt;br /&gt;
&lt;br /&gt;
=== Test mode banner ===&lt;br /&gt;
&lt;br /&gt;
While live mode is off, the dashboard, the setup page and the transaction list all display the same warning as the official Stripe module. It is impossible to forget you are working in test mode.&lt;br /&gt;
&lt;br /&gt;
=== Menus ===&lt;br /&gt;
&lt;br /&gt;
Everything sits under '''Banks and cash → Stripe account''' (the official module's menu), flat, as three entries at the same level:&lt;br /&gt;
&lt;br /&gt;
# Stripe dashboard&lt;br /&gt;
# Stripe transactions&lt;br /&gt;
# CSV import ''(administrators only)''&lt;br /&gt;
&lt;br /&gt;
A dashboard link is also added automatically on the bank account record configured as the Stripe account.&lt;br /&gt;
&lt;br /&gt;
== 9. Scheduled job ==&lt;br /&gt;
&lt;br /&gt;
There are two ways to run the sync, both idempotent and safe to re-run. In both cases the code executed is strictly the same: no behavioural difference between the two triggers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #d33; background:#fee7e6; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''⚠ Neither of them starts on its own.'''&lt;br /&gt;
&lt;br /&gt;
Activating the module creates the &amp;lt;code&amp;gt;StripeAccountingSync&amp;lt;/code&amp;gt; job, but '''disabled by default'''. And even once enabled, the Dolibarr scheduler is triggered by nothing until a system crontab calls it. Without both steps, the sync only happens when &amp;quot;Sync now&amp;quot; is clicked manually.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Step 1 — enable the job ===&lt;br /&gt;
&lt;br /&gt;
Under '''Home → Setup → Modules → Scheduled jobs'''. Since &amp;lt;code&amp;gt;llx_cronjob&amp;lt;/code&amp;gt; is a core table, this setting is made through the interface only, never by direct SQL from the module.&lt;br /&gt;
&lt;br /&gt;
=== Step 2 — a system trigger ===&lt;br /&gt;
&lt;br /&gt;
Pick either option.&lt;br /&gt;
&lt;br /&gt;
'''Option A — Dolibarr scheduler''' ''(recommended when several Dolibarr scheduled jobs coexist)''. Runs every due job, not just this one. Requires step 1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
*/15 * * * * curl &amp;quot;https://your-dolibarr/public/cron/cron_run_jobs_by_url.php?securitykey=YOUR_KEY&amp;amp;userlogin=YOUR_LOGIN&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The security key is generated on the scheduled jobs page, &amp;quot;Security of job execution by URL&amp;quot; button.&lt;br /&gt;
&lt;br /&gt;
'''Option B — the module's CLI script.''' Standalone, refuses to run from a browser, and independent of whether the Dolibarr job is enabled.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
*/15 * * * * php /path/to/htdocs/custom/stripeaccounting/cron/stripe_sync.php &amp;gt;&amp;gt; /var/log/stripeaccounting.log 2&amp;gt;&amp;amp;1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 10. Logging and permissions ==&lt;br /&gt;
&lt;br /&gt;
=== Logging ===&lt;br /&gt;
&lt;br /&gt;
Every API call, generated entry, warning or error is traced in &amp;lt;code&amp;gt;llx_stripeaccounting_log&amp;lt;/code&amp;gt;, readable in the database or through the standard Dolibarr log file. Levels: &amp;lt;code&amp;gt;DEBUG&amp;lt;/code&amp;gt; &amp;lt; &amp;lt;code&amp;gt;INFO&amp;lt;/code&amp;gt; &amp;lt; &amp;lt;code&amp;gt;WARNING&amp;lt;/code&amp;gt; &amp;lt; &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;context&amp;lt;/code&amp;gt; column holds the structured detail as JSON (API payload, computed amounts…).&lt;br /&gt;
&lt;br /&gt;
=== Permissions ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Right !! Controls&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;read&amp;lt;/code&amp;gt; || Access to the dashboard and the transaction list&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;write&amp;lt;/code&amp;gt; || Declared for configuration, but not checked in the code today&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;reconcile&amp;lt;/code&amp;gt; || Manual sync triggering&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In practice, &amp;lt;code&amp;gt;admin/setup.php&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;import.php&amp;lt;/code&amp;gt; only check '''Dolibarr administrator''' status, not the &amp;lt;code&amp;gt;write&amp;lt;/code&amp;gt; right: only administrators can configure the module or import a CSV, whatever is ticked in the module permissions.&lt;br /&gt;
&lt;br /&gt;
== 11. Database schema ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;llx_stripeaccounting_transaction&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
One row per processed Stripe object — charge, fee, refund, dispute or payout — all in the same table, distinguished by the &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt; column.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:24%;&amp;quot; | Column !! style=&amp;quot;width:16%;&amp;quot; | Type !! Role&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rowid&amp;lt;/code&amp;gt; || int AI || Primary key&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;entity&amp;lt;/code&amp;gt; || int || Dolibarr multi-company&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_object_id&amp;lt;/code&amp;gt; || varchar(80) || Stripe identifier — '''idempotency anchor'''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_event_id&amp;lt;/code&amp;gt; || varchar(80) || Event identifier, informational only&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt; || varchar(20) || &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;refund&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;dispute&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;other&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_source_id&amp;lt;/code&amp;gt; || varchar(80) || Source Stripe object (e.g. the charge behind a refund)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;source_label&amp;lt;/code&amp;gt; || varchar(80) || Free-text label entered at CSV import; empty for API rows&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;description&amp;lt;/code&amp;gt; || varchar(255) || Stripe label&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;amount&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;net&amp;lt;/code&amp;gt; || decimal(24,8) || Amounts already converted from Stripe cents&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;currency&amp;lt;/code&amp;gt; || varchar(3) || ISO currency code&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;date_created&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;date_available_on&amp;lt;/code&amp;gt; || datetime || Stripe-side dates&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_facture&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fk_paiement&amp;lt;/code&amp;gt; || int || Resolved Dolibarr invoice and payment, if found&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; || int || Generated &amp;lt;code&amp;gt;llx_bank&amp;lt;/code&amp;gt; line ''(empty for a fee in &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; VAT mode)''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;piece_num&amp;lt;/code&amp;gt; || varchar(20) || Generated accounting piece number, where there is one&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt; || varchar(16) || &amp;lt;code&amp;gt;pending&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ignored&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;error_message&amp;lt;/code&amp;gt; || text || Detail on failure&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;date_creation&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;date_processed&amp;lt;/code&amp;gt; || datetime || Technical timestamps&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_user_creat&amp;lt;/code&amp;gt; || int || User who triggered the processing&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Unique key''' on &amp;lt;code&amp;gt;(stripe_object_id, entity)&amp;lt;/code&amp;gt; — this is what guarantees the same Stripe object can never be inserted twice, even with concurrent executions.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;llx_stripeaccounting_log&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Column !! Role&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;level&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;DEBUG&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;INFO&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;WARNING&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;message&amp;lt;/code&amp;gt; || Short message&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;context&amp;lt;/code&amp;gt; || Structured context as JSON&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_stripeaccounting_transaction&amp;lt;/code&amp;gt; || Related transaction, where applicable&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;datec&amp;lt;/code&amp;gt; || Timestamp&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 12. Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:26%;&amp;quot; | Symptom !! Likely cause !! Action&lt;br /&gt;
|-&lt;br /&gt;
| The &amp;quot;Sync now&amp;quot; button is disabled || Minimum configuration incomplete || Fill in the fields listed in the setup page banner&lt;br /&gt;
|-&lt;br /&gt;
| A transaction stays in &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; || Entry rejected by Dolibarr (non-existent account, closed period), or refund not matched || Read &amp;lt;code&amp;gt;error_message&amp;lt;/code&amp;gt; on the row, then the detail in the log table&lt;br /&gt;
|-&lt;br /&gt;
| The Stripe balance is not displayed || API key missing or invalid in the official Stripe module || Check &amp;lt;code&amp;gt;stripe/admin/stripe.php&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| A refund is never reconciled || The original payment was not found through &amp;lt;code&amp;gt;ext_payment_id&amp;lt;/code&amp;gt; || Check that the Stripe payment was recorded by the official module with that identifier&lt;br /&gt;
|-&lt;br /&gt;
| A &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt; stays in &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; || Stripe supplier third party not set, or has no supplier accounting code || Fill the field in setup, and complete the third party record&lt;br /&gt;
|-&lt;br /&gt;
| A CSV-imported refund stays in &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; || '''Normal and expected''' — that account is not linked to &amp;lt;code&amp;gt;ext_payment_id&amp;lt;/code&amp;gt; || Handle the invoice and refund manually in accounting&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 13. Pitfalls encountered ==&lt;br /&gt;
&lt;br /&gt;
Development notes, kept so nobody falls into them again.&lt;br /&gt;
&lt;br /&gt;
* '''&amp;lt;code&amp;gt;PaymentVarious::create()&amp;lt;/code&amp;gt;''' only updates &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; in the database, never on the PHP object. A &amp;lt;code&amp;gt;fetch()&amp;lt;/code&amp;gt; after &amp;lt;code&amp;gt;create()&amp;lt;/code&amp;gt; is required to get the real value.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;select_comptes()&amp;lt;/code&amp;gt;''' prints its own HTML ''and'' returns the number of accounts. Call it as a bare statement: wrapping it in &amp;lt;code&amp;gt;print&amp;lt;/code&amp;gt; would display that number right after the select tag.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;master.inc.php&amp;lt;/code&amp;gt;, not &amp;lt;code&amp;gt;main.inc.php&amp;lt;/code&amp;gt;''' for the CLI script. The latter expects an HTTP session and, in pure CLI, exits silently — no output, no log, return code 0 — inside its redirect to the login page. This gives the misleading impression that the script &amp;quot;does nothing&amp;quot; rather than a real error.&lt;br /&gt;
* '''Core libraries''' — &amp;lt;code&amp;gt;master.inc.php&amp;lt;/code&amp;gt; does not load everything &amp;lt;code&amp;gt;main.inc.php&amp;lt;/code&amp;gt; loads for the web (e.g. &amp;lt;code&amp;gt;core/lib/date.lib.php&amp;lt;/code&amp;gt;, required by &amp;lt;code&amp;gt;BookKeeping&amp;lt;/code&amp;gt;). Include them explicitly if the CLI script evolves.&lt;br /&gt;
* '''The &amp;quot;nothing selected&amp;quot; option is &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;''' in accounting account selectors — see the Configuration section.&lt;br /&gt;
&lt;br /&gt;
== 14. Known limitations ==&lt;br /&gt;
&lt;br /&gt;
* '''Zero-decimal currencies''' (JPY, KRW…) are not handled: amounts are divided by 100 assuming two decimals. Intended use: EUR.&lt;br /&gt;
* '''The 35-day window''' is not configurable. A sync interrupted for longer must be caught up manually.&lt;br /&gt;
* '''Refund matching''' — relies on &amp;lt;code&amp;gt;ext_payment_id&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ext_payment_site&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;llx_paiement&amp;lt;/code&amp;gt;, filled in by the standard Stripe payment flow. A payment recorded any other way cannot be matched automatically. Matching goes through the '''PaymentIntent id''', never the charge id: the core Stripe module never stores the latter ''(it stores either the raw PaymentIntent, or a composite value, depending on the payment path taken)''.&lt;br /&gt;
* '''CSV import assumes French notation''': an export with a decimal point would not be parsed correctly.&lt;br /&gt;
* '''The &amp;quot;Transfer&amp;quot; column of the Payments CSV''' is stored for information only: it is not used to check that the sum of payments matches the imported payout amount.&lt;br /&gt;
* '''CSV-imported refunds always land in &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;''' — intended behaviour, not a bug.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; VAT mode''' — the Stripe account's bank balance does not reflect the fees, see section 5.&lt;br /&gt;
&lt;br /&gt;
[[Category:Dolibarr]]&lt;br /&gt;
[[Category:Modules]]&lt;br /&gt;
[[Category:Accounting]]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Stripeaccounting&amp;diff=552</id>
		<title>Stripeaccounting</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Stripeaccounting&amp;diff=552"/>
				<updated>2026-08-02T12:40:16Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:StripeAccounting — Documentation technique}}&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Us.png|32px|link=Stripeaccounting/en|English documentation]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border:1px solid #c8ccd1; background:#f8f9fa; border-radius:4px; padding:1em 1.2em; margin:0 0 1.5em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''StripeAccounting''' est un module Dolibarr de '''rapprochement comptable Stripe'''.&lt;br /&gt;
&lt;br /&gt;
Il lit l'API Stripe (ou un export CSV), repère les mouvements que le module Stripe officiel ne comptabilise pas — frais, remboursements, litiges, virements — et pose les écritures manquantes.&lt;br /&gt;
&lt;br /&gt;
: '''Compatibilité''' — Dolibarr 17+, PHP 7.2 → 8.5&lt;br /&gt;
: '''Dépend de''' — modules Stripe, Banque, Comptabilité en partie double&lt;br /&gt;
: '''Voir aussi''' — [[README-fr|Installation et guide utilisateur]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== 1. Principes de fonctionnement ==&lt;br /&gt;
&lt;br /&gt;
Quatre règles gouvernent tout le module.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:22%;&amp;quot; | Principe !! Ce que ça veut dire&lt;br /&gt;
|-&lt;br /&gt;
| '''Complémentaire''' || Le module ne crée aucun paiement, aucune facture, aucun webhook. Il lit Stripe et complète la comptabilité, rien de plus.&lt;br /&gt;
|-&lt;br /&gt;
| '''Idempotent''' || Chaque objet Stripe n'est traité qu'une fois, quel que soit le nombre de relances de la synchronisation.&lt;br /&gt;
|-&lt;br /&gt;
| '''Jamais de devinette''' || Si une opération ne peut pas être rattachée avec certitude, rien n'est posté : la ligne passe en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; pour revue manuelle.&lt;br /&gt;
|-&lt;br /&gt;
| '''Configuration bloquante''' || Tant que la configuration minimale est incomplète, aucune synchronisation ne démarre (ni bouton, ni cron, ni import).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2. Prérequis ==&lt;br /&gt;
&lt;br /&gt;
=== Modules Dolibarr requis ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Module !! Ce qu'il apporte&lt;br /&gt;
|-&lt;br /&gt;
| '''Stripe''' (&amp;lt;code&amp;gt;modStripe&amp;lt;/code&amp;gt;) || Clé API, mode test/live, compte financier Stripe&lt;br /&gt;
|-&lt;br /&gt;
| '''Banque''' (&amp;lt;code&amp;gt;modBanque&amp;lt;/code&amp;gt;) || Tables &amp;lt;code&amp;gt;llx_bank&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;llx_bank_account&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| '''Comptabilité en partie double''' (&amp;lt;code&amp;gt;modAccounting&amp;lt;/code&amp;gt;) || Table &amp;lt;code&amp;gt;llx_accounting_bookkeeping&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Réglage Dolibarr indispensable ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ACCOUNTING_ACCOUNT_TRANSFER_CASH&amp;lt;/code&amp;gt; doit être renseigné dans '''Comptabilité → Configuration → Comptes par défaut'''. Sans lui, le virement interne généré par les payouts ne peut pas être transféré en comptabilité (limite de Dolibarr, pas du module).&lt;br /&gt;
&lt;br /&gt;
l’option s'appelle : '''Compte comptable par défaut pour les virements internes'''&lt;br /&gt;
&lt;br /&gt;
=== Notes ===&lt;br /&gt;
&lt;br /&gt;
* Le SDK PHP Stripe n'est pas dupliqué : le module réutilise la copie du cœur (&amp;lt;code&amp;gt;includes/stripe/stripe-php/&amp;lt;/code&amp;gt;).&lt;br /&gt;
* Le code évite volontairement toute syntaxe PHP postérieure à 7.2 (pas de &amp;lt;code&amp;gt;match&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;?-&amp;gt;&amp;lt;/code&amp;gt;, enums, propriétés typées, &amp;lt;code&amp;gt;str_contains&amp;lt;/code&amp;gt;…) pour couvrir toute la plage 7.2 → 8.5.&lt;br /&gt;
&lt;br /&gt;
== 3. Arborescence ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
custom/stripeaccounting/&lt;br /&gt;
├── core/modules/modStripeAccounting.class.php   Descripteur (droits, menus, cron, constantes)&lt;br /&gt;
├── class/&lt;br /&gt;
│   ├── StripeApi.class.php                      Wrapper SDK Stripe (lecture seule)&lt;br /&gt;
│   ├── StripeRepository.class.php               Accès SQL + idempotence&lt;br /&gt;
│   ├── StripeLogger.class.php                   Journalisation&lt;br /&gt;
│   ├── StripeAccounting.class.php               Génération des écritures&lt;br /&gt;
│   ├── StripePayout.class.php                   Rapprochement des virements&lt;br /&gt;
│   ├── StripeSync.class.php                     Orchestrateur (point d'entrée du cron)&lt;br /&gt;
│   ├── StripeCsvImporter.class.php              Import CSV&lt;br /&gt;
│   └── actions_stripeaccounting.class.php       Hook 'bankcard'&lt;br /&gt;
├── admin/setup.php                              Configuration&lt;br /&gt;
├── import.php                                   Import CSV&lt;br /&gt;
├── dashboard.php                                Tableau de bord&lt;br /&gt;
├── transaction_list.php                         Liste des transactions&lt;br /&gt;
├── cron/stripe_sync.php                         Point d'entrée CLI&lt;br /&gt;
├── lib/stripeaccounting.lib.php&lt;br /&gt;
├── sql/&lt;br /&gt;
├── langs/{fr_FR,en_US,es_ES,it_IT,de_DE}/&lt;br /&gt;
└── css/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sens des dépendances ===&lt;br /&gt;
&lt;br /&gt;
: pages et hook → &amp;lt;code&amp;gt;StripeSync&amp;lt;/code&amp;gt; → (&amp;lt;code&amp;gt;StripeApi&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StripeRepository&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StripeAccounting&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StripePayout&amp;lt;/code&amp;gt;) → &amp;lt;code&amp;gt;StripeLogger&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:26%;&amp;quot; | Classe !! Rôle&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeApi&amp;lt;/code&amp;gt; || Interroge le SDK Stripe (balance transactions, charges, remboursements, litiges, payouts) avec pagination automatique. Aucun accès base, aucune écriture.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeRepository&amp;lt;/code&amp;gt; || Tout le SQL des deux tables du module. &amp;lt;code&amp;gt;upsertTransaction()&amp;lt;/code&amp;gt; est le point d'idempotence.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeLogger&amp;lt;/code&amp;gt; || Écrit dans &amp;lt;code&amp;gt;llx_stripeaccounting_log&amp;lt;/code&amp;gt; et en miroir dans &amp;lt;code&amp;gt;dol_syslog()&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeAccounting&amp;lt;/code&amp;gt; || Construit les écritures (remboursement, litige, TVA autoliquidation) ou les mouvements bancaires (frais). Expose &amp;lt;code&amp;gt;checkConfig()&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripePayout&amp;lt;/code&amp;gt; || Crée le virement bancaire interne entre le compte Stripe et la banque réelle.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeSync&amp;lt;/code&amp;gt; || Orchestrateur : une méthode par flux, plus &amp;lt;code&amp;gt;reconcileStripeAccount()&amp;lt;/code&amp;gt; qui enchaîne tout.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeCsvImporter&amp;lt;/code&amp;gt; || Alimente le même pipeline depuis un export CSV Stripe.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ActionsStripeAccounting&amp;lt;/code&amp;gt; || Hook &amp;lt;code&amp;gt;bankcard&amp;lt;/code&amp;gt; : lien vers le tableau de bord sur la fiche du compte Stripe.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 4. Synchronisation et idempotence ==&lt;br /&gt;
&lt;br /&gt;
Chaque flux (&amp;lt;code&amp;gt;syncFees&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncRefunds&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncDisputes&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncPayouts&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncTransactions&amp;lt;/code&amp;gt;) suit toujours les mêmes étapes :&lt;br /&gt;
&lt;br /&gt;
# '''Vérifier la configuration''' — si elle est incomplète : log &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt;, arrêt immédiat, aucun appel API.&lt;br /&gt;
# '''Lister les objets Stripe''' sur une fenêtre glissante de '''35 jours'''.&lt;br /&gt;
# '''Filtrer''' — un objet est ignoré seulement s'il existe déjà ''et'' que son statut est &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;ignored&amp;lt;/code&amp;gt;. Une ligne en &amp;lt;code&amp;gt;pending&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; est '''retentée''' à ce run.&lt;br /&gt;
# '''Enregistrer''' en statut &amp;lt;code&amp;gt;pending&amp;lt;/code&amp;gt;, puis générer l'écriture ou le mouvement bancaire.&lt;br /&gt;
# '''Conclure''' — succès : statut &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt;. Échec : statut &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; avec le message, et '''le lot continue''' sur l'objet suivant.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #36c; background:#eaf3ff; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Reprise automatique''' — une ligne en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; redevient éligible au run suivant. Une fois la cause corrigée (par exemple un exercice comptable créé tardivement), aucune intervention manuelle n'est nécessaire.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi les doublons sont impossibles ===&lt;br /&gt;
&lt;br /&gt;
* '''Clé unique en base''' sur &amp;lt;code&amp;gt;(stripe_object_id, entity)&amp;lt;/code&amp;gt; — protège même contre deux exécutions concurrentes du cron.&lt;br /&gt;
* '''Test explicite avant traitement''' — évite jusqu'à la tentative d'écriture pour un objet déjà finalisé.&lt;br /&gt;
&lt;br /&gt;
=== Cas particuliers : &amp;lt;code&amp;gt;adjustment&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;payment_failure_refund&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Ce sont des corrections de solde effectuées par Stripe lui-même (réversion après litige, remboursement d'un paiement finalement échoué). Le module les '''enregistre''' — sinon elles resteraient invisibles — mais ne les comptabilise '''jamais''' automatiquement : le signe du montant et la cause varient trop. Elles sont créées directement en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, avec un message explicite, à traiter manuellement.&lt;br /&gt;
&lt;br /&gt;
== 5. Écritures comptables ==&lt;br /&gt;
&lt;br /&gt;
Toutes les lignes d'un même évènement partagent le triplet &amp;lt;code&amp;gt;doc_type='stripeaccounting'&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fk_doc&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;doc_ref&amp;lt;/code&amp;gt; : Dolibarr les regroupe automatiquement sous un même numéro de pièce, sans numérotation propre au module.&lt;br /&gt;
&lt;br /&gt;
=== Vue d'ensemble ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! Évènement !! Ce que fait le module !! Résultat comptable&lt;br /&gt;
|-&lt;br /&gt;
| Frais Stripe ''(TVA &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt;)'' || Mouvement bancaire &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; || Écriture 627xxx / 517xxx générée plus tard par Dolibarr&lt;br /&gt;
|-&lt;br /&gt;
| Frais Stripe ''(mode &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt;)'' || En plus : paire TVA postée immédiatement || Débit TVA déductible, crédit TVA autoliquidation ''(impact net nul)''&lt;br /&gt;
|-&lt;br /&gt;
| Frais Stripe ''(mode &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt;)'' || Écriture directe complète || Débit compte de frais HT + TVA déductible, crédit compte Stripe TTC&lt;br /&gt;
|-&lt;br /&gt;
| Frais d'abonnement / service ''(Radar, Billing, Connect…)'' || Mouvement bancaire &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; || Écriture générée plus tard par Dolibarr, sur le compte fournisseur Stripe&lt;br /&gt;
|-&lt;br /&gt;
| Virement (payout) || Virement bancaire interne entre les 2 comptes || Écriture générée plus tard par Dolibarr&lt;br /&gt;
|-&lt;br /&gt;
| Remboursement ''(facture retrouvée)'' || Écriture directe || Débit compte client 411xxx, crédit compte Stripe 517xxx&lt;br /&gt;
|-&lt;br /&gt;
| Remboursement ''(facture introuvable)'' || Rien || Statut &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, à traiter manuellement&lt;br /&gt;
|-&lt;br /&gt;
| Litige / chargeback || Écriture directe || Débit perte sur litiges 658xxx, crédit compte Stripe 517xxx ''(+ compte de frais si frais associés)''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi frais et virements ne génèrent pas d'écriture directe ===&lt;br /&gt;
&lt;br /&gt;
Le problème historique : quand une facture Stripe est transférée en comptabilité par le workflow standard de Dolibarr, le paiement est comptabilisé pour son montant '''brut''' — les frais sont ignorés à cette étape.&lt;br /&gt;
&lt;br /&gt;
Si le module postait ''en plus'' sa propre écriture ''et'' sa propre ligne bancaire, cette ligne resterait invisible pour &amp;lt;code&amp;gt;bankjournal.php&amp;lt;/code&amp;gt; — qui ne reconnaît que les lignes rattachées à &amp;lt;code&amp;gt;doc_type='bank'&amp;lt;/code&amp;gt;. Un administrateur transférant « normalement » le compte bancaire en comptabilité créait alors une '''seconde''' écriture pour le même mouvement.&lt;br /&gt;
&lt;br /&gt;
'''La solution retenue :''' pour les frais, les frais d'abonnement et les virements, le module ne crée plus que le '''mouvement bancaire réel''', avec les mécanismes natifs de Dolibarr. C'est ensuite le bouton natif ''« Transférer en comptabilité »'' qui produit l'écriture, comme pour n'importe quel autre mouvement bancaire. Le module ne touche donc plus du tout &amp;lt;code&amp;gt;llx_accounting_bookkeeping&amp;lt;/code&amp;gt; dans ces trois cas.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:22%;&amp;quot; | Cas !! Mécanisme natif utilisé&lt;br /&gt;
|-&lt;br /&gt;
| Frais et frais d'abonnement || &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; (mouvement bancaire avec compte de contrepartie, sans tiers ni facture), avec son propre &amp;lt;code&amp;gt;accountancy_code&amp;lt;/code&amp;gt; que &amp;lt;code&amp;gt;bankjournal.php&amp;lt;/code&amp;gt; lit directement.&lt;br /&gt;
|-&lt;br /&gt;
| Virements (payouts) || Virement interne Dolibarr : &amp;lt;code&amp;gt;Account::addline()&amp;lt;/code&amp;gt; des deux côtés, plus &amp;lt;code&amp;gt;add_url_line(…, 'banktransfert')&amp;lt;/code&amp;gt;. La contrepartie est imputée sur &amp;lt;code&amp;gt;ACCOUNTING_ACCOUNT_TRANSFER_CASH&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Dans les deux cas, le statut passe à &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt; — le module a fini son travail — mais '''&amp;lt;code&amp;gt;piece_num&amp;lt;/code&amp;gt; reste vide''' : l'écriture n'existe pas encore, seul &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; est renseigné. Après transfert manuel, on la retrouve avec &amp;lt;code&amp;gt;doc_type='bank'&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;fk_doc&amp;lt;/code&amp;gt; égal au &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; de la ligne.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #fc3; background:#fef6e7; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''À savoir''' — l'écriture des virements ne s'équilibre à zéro sur le compte de transfert que lorsque '''les deux''' comptes bancaires (Stripe ''et'' la banque réelle) ont été transférés en comptabilité, pas seulement un des deux.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #d33; background:#fee7e6; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''⚠ &amp;lt;code&amp;gt;STRIPE_AUTO_RECORD_PAYOUT&amp;lt;/code&amp;gt; doit rester désactivé'''&lt;br /&gt;
&lt;br /&gt;
Dès lors que ce module gère les virements, décochez « Activer l'enregistrement automatique des paiements Stripe » dans &amp;lt;code&amp;gt;stripe/admin/stripe.php&amp;lt;/code&amp;gt; — malgré son libellé, cette case ne concerne que les virements.&lt;br /&gt;
&lt;br /&gt;
Sinon, le webhook du module officiel et ce module créeraient chacun leur propre mouvement bancaire pour le même virement, sans le savoir l'un de l'autre.&lt;br /&gt;
&lt;br /&gt;
Le webhook cœur ne conserve d'ailleurs '''aucune''' trace de l'id du virement traité : en cas de double livraison Stripe (garantie « au moins une fois »), rien ne l'empêche de doublonner tout seul. Ce module, lui, a une vraie idempotence et rattrape automatiquement tout virement manqué sur 35 jours.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Page « Transferts Stripe » masquée ===&lt;br /&gt;
&lt;br /&gt;
À l'activation, &amp;lt;code&amp;gt;modStripeAccounting::init()&amp;lt;/code&amp;gt; désactive l'entrée de menu &amp;lt;code&amp;gt;stripe/payout.php&amp;lt;/code&amp;gt; : cette page interroge l'API en direct sans rien enregistrer, et sa coexistence avec ce module ne créerait qu'une confusion sur ce qui fait foi pour les virements. &amp;lt;code&amp;gt;remove()&amp;lt;/code&amp;gt; restaure la condition d'origine. '''C'est la seule table du cœur que ce module modifie''' — délibéré, et documenté ici pour cette raison.&lt;br /&gt;
&lt;br /&gt;
=== Frais par transaction ou frais d'abonnement ? ===&lt;br /&gt;
&lt;br /&gt;
Stripe facture deux choses distinctes sous le mot « frais » :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! !! Frais par transaction !! Frais d'abonnement / service&lt;br /&gt;
|-&lt;br /&gt;
! Exemple&lt;br /&gt;
| Commission sur chaque encaissement || Radar, Billing, Connect&lt;br /&gt;
|-&lt;br /&gt;
! Où le trouver&lt;br /&gt;
| Champ &amp;lt;code&amp;gt;.fee&amp;lt;/code&amp;gt; d'une balance transaction de type &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; || Balance transaction dédiée, de type &amp;lt;code&amp;gt;stripe_fee&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;application_fee&amp;lt;/code&amp;gt; ''(le &amp;lt;code&amp;gt;.fee&amp;lt;/code&amp;gt; y vaut toujours 0, le montant est dans &amp;lt;code&amp;gt;.amount&amp;lt;/code&amp;gt;)''&lt;br /&gt;
|-&lt;br /&gt;
! Compte utilisé&lt;br /&gt;
| Compte de frais configuré (627xxx) || Code comptable fournisseur du tiers Stripe configuré&lt;br /&gt;
|-&lt;br /&gt;
! Type en base&lt;br /&gt;
| &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Limite du mode TVA &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Ce mode doit scinder le montant TTC en HT + TVA, un découpage que &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; ne sait pas exprimer. Il reste donc sur l'ancien comportement : écriture directe complète, aucun mouvement bancaire créé. Pas de risque de doublon (puisque aucune ligne bancaire n'est produite), mais le solde &amp;lt;code&amp;gt;llx_bank&amp;lt;/code&amp;gt; du compte Stripe ne reflétera jamais les frais tant que ce mode est actif.&lt;br /&gt;
&lt;br /&gt;
== 6. Import CSV ==&lt;br /&gt;
&lt;br /&gt;
L'import couvre le cas d'un compte Stripe '''différent''' de celui configuré dans le module officiel — par exemple une autre boutique PrestaShop avec son propre compte marchand. L'API n'y a pas accès : le contenu est exporté en CSV depuis le dashboard Stripe, puis importé.&lt;br /&gt;
&lt;br /&gt;
=== Hypothèse de départ ===&lt;br /&gt;
&lt;br /&gt;
Les factures et paiements de cette boutique sont '''déjà''' comptabilisés dans Dolibarr par un autre processus, et l'encaissement (débit 517, crédit 411) est déjà posé. Seuls manquent les '''frais''', les '''remboursements''' et les '''virements''' — c'est exactement ce que l'import traite.&lt;br /&gt;
&lt;br /&gt;
=== Interface : un seul champ ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;import.php&amp;lt;/code&amp;gt; n'expose plus qu'un champ d'upload, '''Historique général''', câblé sur &amp;lt;code&amp;gt;importGeneralHistory()&amp;lt;/code&amp;gt;. Ce fichier couvre à lui seul tous les types de mouvements.&lt;br /&gt;
&lt;br /&gt;
Les méthodes &amp;lt;code&amp;gt;importPayments()&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;importPayouts()&amp;lt;/code&amp;gt; restent implémentées et fonctionnelles, mais ne sont plus atteignables depuis l'interface ; elles sont documentées ci-dessous pour mémoire.&lt;br /&gt;
&lt;br /&gt;
Comme le bouton « Synchroniser maintenant », l'import est bloqué — bandeau d'alerte, bouton désactivé, garde-fou côté serveur — tant que la configuration est incomplète.&lt;br /&gt;
&lt;br /&gt;
=== Les trois méthodes ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:24%;&amp;quot; | Méthode !! Export Stripe lu !! Traitement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;importGeneralHistory()&amp;lt;/code&amp;gt;&amp;lt;br /&amp;gt;''(seule exposée)'' || Balance history || Aiguillage par colonne &amp;lt;code&amp;gt;Type&amp;lt;/code&amp;gt;, voir tableau ci-dessous&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;importPayments()&amp;lt;/code&amp;gt; || Payments || Frais → écriture de frais. Montant remboursé → ligne &amp;lt;code&amp;gt;refund&amp;lt;/code&amp;gt; toujours en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;importPayouts()&amp;lt;/code&amp;gt; || Payouts || Exactement le même traitement qu'un payout venu de l'API&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Aiguillage de l'historique général, par colonne &amp;lt;code&amp;gt;Type&amp;lt;/code&amp;gt; :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:30%;&amp;quot; | Type Stripe !! Traitement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt; || Virement bancaire interne, comme via l'API&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;payment&amp;lt;/code&amp;gt; avec frais || Mouvement de frais&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_fee&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;application_fee&amp;lt;/code&amp;gt; || Frais d'abonnement, sur le compte fournisseur Stripe&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;refund&amp;lt;/code&amp;gt; || Enregistré, '''toujours''' en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;payout_minimum_balance_hold&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;…_release&amp;lt;/code&amp;gt; || '''Ignorés''' — réserve glissante Stripe, impact net nul, rien à comptabiliser&lt;br /&gt;
|-&lt;br /&gt;
| tout autre type || Enregistré en &amp;lt;code&amp;gt;type='other'&amp;lt;/code&amp;gt;, statut &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, type brut conservé dans la description. Aucune écriture devinée.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les colonnes sont reconnues '''par leur nom''' : l'ordre importe peu, et les colonnes en plus non utilisées sont ignorées.&lt;br /&gt;
&lt;br /&gt;
=== Idempotence de l'import ===&lt;br /&gt;
&lt;br /&gt;
La clé unique protège contre tout double import : réimporter le même CSV, ou un CSV qui chevauche un import précédent, ne crée aucun doublon.&lt;br /&gt;
&lt;br /&gt;
Point important : dans l'historique général, les lignes &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;payment&amp;lt;/code&amp;gt; sont indexées par leur colonne '''&amp;lt;code&amp;gt;Source&amp;lt;/code&amp;gt;''' (&amp;lt;code&amp;gt;po_…&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ch_…&amp;lt;/code&amp;gt;), pas par l'&amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt; de la ligne (&amp;lt;code&amp;gt;txn_…&amp;lt;/code&amp;gt;) — soit exactement la même clé que les imports dédiés. Importer l'historique général '''en plus''' des exports spécifiques ne poste donc jamais deux fois la même écriture, quel que soit l'ordre.&lt;br /&gt;
&lt;br /&gt;
Les identifiants Stripe étant uniques à l'échelle de la plateforme, mélanger dans la même table des lignes venant du compte API et de plusieurs comptes importés en CSV ne présente aucun risque de collision.&lt;br /&gt;
&lt;br /&gt;
=== Détails pratiques ===&lt;br /&gt;
&lt;br /&gt;
* '''Libellé source''' — un champ libre saisi à l'import (ex. « Boutique DRM ») est stocké sur chaque ligne créée et sert de colonne et de filtre dans la liste, pour distinguer plusieurs boutiques côte à côte.&lt;br /&gt;
* '''Format des montants''' — les CSV Stripe utilisent la virgule décimale française, convertie via &amp;lt;code&amp;gt;price2num()&amp;lt;/code&amp;gt;. Les dates marquées &amp;lt;code&amp;gt;(UTC)&amp;lt;/code&amp;gt; sont interprétées comme telles.&lt;br /&gt;
&lt;br /&gt;
== 7. Configuration ==&lt;br /&gt;
&lt;br /&gt;
La clé API et le mode test/live ne sont '''pas''' ressaisis ici : ils sont lus en lecture seule depuis le module Stripe officiel.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:26%;&amp;quot; | Champ !! Constante !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| Compte financier Stripe || &amp;lt;code&amp;gt;STRIPE_BANK_ACCOUNT_FOR_PAYMENTS&amp;lt;/code&amp;gt; ''(constante du module officiel)'' || Sélecteur de compte bancaire. Aucune copie locale, donc aucun risque de divergence.&lt;br /&gt;
|-&lt;br /&gt;
| Compte bancaire principal || &amp;lt;code&amp;gt;STRIPE_BANK_ACCOUNT_FOR_BANKTRANSFERS&amp;lt;/code&amp;gt; ''(constante du module officiel)'' || Même sélecteur. Voir l'encadré ci-dessous.&lt;br /&gt;
|-&lt;br /&gt;
| Compte de frais || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_FRAIS&amp;lt;/code&amp;gt; || Numéro de compte, ex. 627xxx&lt;br /&gt;
|-&lt;br /&gt;
| Compte de litiges || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_LITIGES&amp;lt;/code&amp;gt; || Numéro de compte, ex. 658xxx. '''Requis''' — utilisé dès qu'un litige survient, quel que soit le mode TVA.&lt;br /&gt;
|-&lt;br /&gt;
| Tiers fournisseur Stripe || &amp;lt;code&amp;gt;STRIPEACCOUNTING_FOURNISSEUR_STRIPE_ID&amp;lt;/code&amp;gt; || Tiers marqué fournisseur ; c'est son code comptable fournisseur qui est utilisé. Optionnel, sauf s'il existe des frais d'abonnement.&lt;br /&gt;
|-&lt;br /&gt;
| Mode TVA || &amp;lt;code&amp;gt;STRIPEACCOUNTING_VAT_MODE&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Compte TVA déductible (intracommunautaire) || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_TVA_DEDUCTIBLE&amp;lt;/code&amp;gt; || Requis si mode TVA ≠ &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt;. Stripe facturant toujours depuis une entité UE non française, la TVA déductible est intracommunautaire dans tous les cas.&lt;br /&gt;
|-&lt;br /&gt;
| Compte de TVA due (intracommunautaire) || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_TVA_AUTOLIQUIDATION&amp;lt;/code&amp;gt; || Requis en mode &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt; uniquement — jamais utilisé en mode &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| Taux de TVA || &amp;lt;code&amp;gt;STRIPEACCOUNTING_VAT_RATE&amp;lt;/code&amp;gt; || Pourcentage, 20 par défaut&lt;br /&gt;
|-&lt;br /&gt;
| Fréquence de synchronisation || &amp;lt;code&amp;gt;STRIPEACCOUNTING_SYNC_UNITFREQUENCY&amp;lt;/code&amp;gt; || Répercutée sur la tâche planifiée (en secondes)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #36c; background:#eaf3ff; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Pourquoi redéfinir le compte bancaire principal ici ?'''&lt;br /&gt;
&lt;br /&gt;
La page de configuration du module Stripe officiel n'affiche ce champ que si &amp;lt;code&amp;gt;STRIPE_AUTO_RECORD_PAYOUT&amp;lt;/code&amp;gt; est activé — et son handler de sauvegarde remet la valeur à 0 à chaque enregistrement tant que le champ n'est pas rendu. Or ce réglage doit justement rester désactivé quand ce module gère les virements. Le champ est donc réexposé ici, en écrivant directement la constante du cœur, pour que la valeur reste configurable et stable.&lt;br /&gt;
&lt;br /&gt;
Les deux sélecteurs de compte n'écrivent leur constante que si un compte réel a été soumis : enregistrer la page pour un tout autre champ n'écrase jamais une valeur correcte.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Vérification de la configuration ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;StripeAccounting::checkConfig()&amp;lt;/code&amp;gt; renvoie la liste des constantes manquantes. Elle est appelée à la fois par la page de configuration (bandeau d'information) et par chaque point d'entrée de synchronisation (garde-fou réel qui bloque tout traitement).&lt;br /&gt;
&lt;br /&gt;
=== Piège des sélecteurs de compte comptable ===&lt;br /&gt;
&lt;br /&gt;
Les quatre champs utilisant &amp;lt;code&amp;gt;FormAccounting::select_account()&amp;lt;/code&amp;gt; (frais, litiges, les deux comptes TVA) ont une option « rien sélectionné » dont la valeur est '''&amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;''' — une chaîne non vide, donc vraie en PHP. Un champ laissé vide et enregistré stocke littéralement &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;StripeAccounting::getAccountConst()&amp;lt;/code&amp;gt; normalise cette valeur en chaîne vide à la lecture, partout où ces constantes sont lues. Aucune écriture ne peut donc atterrir sur le compte inexistant &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 8. Interface ==&lt;br /&gt;
&lt;br /&gt;
=== Tableau de bord ===&lt;br /&gt;
&lt;br /&gt;
Solde Stripe (appel API en direct), nombre de transactions non rapprochées, total des frais du mois, payouts en attente, et bouton '''Synchroniser maintenant''' — désactivé, avec bandeau listant les constantes manquantes, tant que la configuration est incomplète.&lt;br /&gt;
&lt;br /&gt;
=== Liste des transactions ===&lt;br /&gt;
&lt;br /&gt;
Liste paginée, triable et filtrable, construite avec le même mécanisme que les listes natives Dolibarr : l'icône en haut à droite du tableau permet à chaque utilisateur de choisir ses colonnes, et la préférence est mémorisée par utilisateur.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:20%;&amp;quot; | Colonne !! Contenu&lt;br /&gt;
|-&lt;br /&gt;
| Montant, Frais, Total || Le popup sur les frais indique la TVA sur frais quand une paire d'autoliquidation ou une TVA française a été postée&lt;br /&gt;
|-&lt;br /&gt;
| Type, Description || Popup avec l'ID Stripe, l'ID d'évènement ou de source, et la description complète non tronquée&lt;br /&gt;
|-&lt;br /&gt;
| Tiers || Le client résolu via la facture, ou via la charge source pour son frais associé, ou le tiers fournisseur Stripe pour un frais d'abonnement&lt;br /&gt;
|-&lt;br /&gt;
| Écriture || Lien « Pièce n°X » vers l'écriture, et/ou lien vers le mouvement bancaire associé — voir la nuance ci-dessous&lt;br /&gt;
|-&lt;br /&gt;
| Source, Statut || Le badge &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; ouvre un popup avec le message d'erreur complet : plus besoin d'aller en base pour comprendre un échec&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #fc3; background:#fef6e7; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Lire la colonne « Écriture »''' — sur une ligne &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt;, le lien pointe vers le '''mouvement bancaire''', pas vers une pièce comptable. Le &amp;lt;code&amp;gt;piece_num&amp;lt;/code&amp;gt; du module, lui, n'est jamais l'écriture 627/517 du frais : c'est uniquement la paire TVA d'autoliquidation. L'écriture du frais est générée plus tard, par le bouton natif de Dolibarr, et n'est jamais reportée sur cette ligne.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La page est '''purement consultative''' : aucune comptabilisation manuelle n'y est proposée. Le module comptabilise automatiquement, et le transfert en comptabilité des frais et virements se fait depuis le bouton natif « Transférer en comptabilité ».&lt;br /&gt;
&lt;br /&gt;
=== Lignes &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Chaque paiement produit '''deux lignes''' en base :&lt;br /&gt;
&lt;br /&gt;
* une ligne &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt;, toujours en statut &amp;lt;code&amp;gt;ignored&amp;lt;/code&amp;gt;, frais à 0, jamais traitée — présente uniquement pour l'idempotence ;&lt;br /&gt;
* une ligne &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; pour le même paiement, liée à la première.&lt;br /&gt;
&lt;br /&gt;
Les deux apparaissent séparément dans la liste, mais la ligne &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; porte elle aussi le lien vers le paiement et la facture, résolu par jointure.&lt;br /&gt;
&lt;br /&gt;
=== Bandeau mode test ===&lt;br /&gt;
&lt;br /&gt;
Tant que le mode live n'est pas activé, le tableau de bord, la page de configuration et la liste des transactions affichent tous les trois le même avertissement que le module Stripe officiel. Impossible d'oublier qu'on travaille en mode test.&lt;br /&gt;
&lt;br /&gt;
=== Menus ===&lt;br /&gt;
&lt;br /&gt;
Tout est regroupé sous '''Banques et caisses → Compte Stripe''' (menu du module officiel), à plat, en trois entrées de même niveau :&lt;br /&gt;
&lt;br /&gt;
# Tableau de bord Stripe&lt;br /&gt;
# Transactions Stripe&lt;br /&gt;
# Import CSV ''(réservé aux administrateurs)''&lt;br /&gt;
&lt;br /&gt;
Un lien vers le tableau de bord est aussi ajouté automatiquement sur la fiche du compte bancaire configuré comme compte Stripe.&lt;br /&gt;
&lt;br /&gt;
== 9. Tâche planifiée ==&lt;br /&gt;
&lt;br /&gt;
Deux façons d'exécuter la synchronisation, toutes deux idempotentes et sans risque à relancer. Dans les deux cas le code exécuté est strictement le même : aucune divergence de comportement.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #d33; background:#fee7e6; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''⚠ Aucune des deux ne démarre toute seule.'''&lt;br /&gt;
&lt;br /&gt;
L'activation du module crée la tâche &amp;lt;code&amp;gt;StripeAccountingSync&amp;lt;/code&amp;gt;, mais '''désactivée par défaut'''. Et même activée, l'ordonnanceur Dolibarr n'est déclenché par rien tant qu'aucune crontab système ne l'appelle. Sans ces deux étapes, la synchro n'a lieu qu'au clic manuel sur « Synchroniser maintenant ».&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Étape 1 — activer la tâche ===&lt;br /&gt;
&lt;br /&gt;
Dans '''Accueil → Configuration → Modules → Tâches planifiées'''. &amp;lt;code&amp;gt;llx_cronjob&amp;lt;/code&amp;gt; étant une table du cœur, ce réglage se fait uniquement par l'interface, jamais en SQL direct depuis le module.&lt;br /&gt;
&lt;br /&gt;
=== Étape 2 — un déclencheur système ===&lt;br /&gt;
&lt;br /&gt;
Au choix, l'une des deux options.&lt;br /&gt;
&lt;br /&gt;
'''Option A — ordonnanceur Dolibarr''' ''(recommandé si plusieurs tâches planifiées coexistent)''. Lance toutes les tâches dues, pas seulement celle-ci. Nécessite l'étape 1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
*/15 * * * * curl &amp;quot;https://votre-dolibarr/public/cron/cron_run_jobs_by_url.php?securitykey=VOTRE_CLE&amp;amp;userlogin=VOTRE_LOGIN&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La clé de sécurité se génère sur la page des tâches planifiées, bouton « Sécurité de l'exécution des tâches par URL ».&lt;br /&gt;
&lt;br /&gt;
'''Option B — script CLI du module.''' Autonome, refuse l'exécution depuis un navigateur, et indépendant de l'état activé ou non de la tâche Dolibarr.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
*/15 * * * * php /chemin/vers/htdocs/custom/stripeaccounting/cron/stripe_sync.php &amp;gt;&amp;gt; /var/log/stripeaccounting.log 2&amp;gt;&amp;amp;1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 10. Journalisation et permissions ==&lt;br /&gt;
&lt;br /&gt;
=== Journalisation ===&lt;br /&gt;
&lt;br /&gt;
Chaque appel API, écriture générée, avertissement ou erreur est tracé dans &amp;lt;code&amp;gt;llx_stripeaccounting_log&amp;lt;/code&amp;gt;, consultable en base ou via le fichier de log standard Dolibarr. Niveaux : &amp;lt;code&amp;gt;DEBUG&amp;lt;/code&amp;gt; &amp;lt; &amp;lt;code&amp;gt;INFO&amp;lt;/code&amp;gt; &amp;lt; &amp;lt;code&amp;gt;WARNING&amp;lt;/code&amp;gt; &amp;lt; &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt;. La colonne &amp;lt;code&amp;gt;context&amp;lt;/code&amp;gt; contient le détail structuré en JSON (payload API, montants calculés…).&lt;br /&gt;
&lt;br /&gt;
=== Permissions ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Droit !! Contrôle&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;read&amp;lt;/code&amp;gt; || Consultation du tableau de bord et de la liste&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;write&amp;lt;/code&amp;gt; || Déclarée pour la configuration, mais non vérifiée dans le code aujourd'hui&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;reconcile&amp;lt;/code&amp;gt; || Déclenchement manuel de la synchronisation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
En pratique, &amp;lt;code&amp;gt;admin/setup.php&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;import.php&amp;lt;/code&amp;gt; ne contrôlent que le statut '''administrateur Dolibarr''', pas le droit &amp;lt;code&amp;gt;write&amp;lt;/code&amp;gt; : seuls les administrateurs peuvent configurer le module ou importer un CSV, quoi qu'il soit coché dans les permissions.&lt;br /&gt;
&lt;br /&gt;
== 11. Base de données ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;llx_stripeaccounting_transaction&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Une ligne par objet Stripe traité — charge, frais, remboursement, litige ou virement — tous dans la même table, distingués par la colonne &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:24%;&amp;quot; | Colonne !! style=&amp;quot;width:16%;&amp;quot; | Type !! Rôle&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rowid&amp;lt;/code&amp;gt; || int AI || Clé primaire&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;entity&amp;lt;/code&amp;gt; || int || Multi-société Dolibarr&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_object_id&amp;lt;/code&amp;gt; || varchar(80) || Identifiant Stripe — '''ancre d'idempotence'''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_event_id&amp;lt;/code&amp;gt; || varchar(80) || Identifiant d'évènement, informatif seulement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt; || varchar(20) || &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;refund&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;dispute&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;other&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_source_id&amp;lt;/code&amp;gt; || varchar(80) || Objet Stripe source (ex. la charge liée à un remboursement)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;source_label&amp;lt;/code&amp;gt; || varchar(80) || Libellé libre saisi à l'import CSV ; vide pour les lignes venues de l'API&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;description&amp;lt;/code&amp;gt; || varchar(255) || Libellé Stripe&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;amount&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;net&amp;lt;/code&amp;gt; || decimal(24,8) || Montants déjà convertis depuis les centimes Stripe&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;currency&amp;lt;/code&amp;gt; || varchar(3) || Code devise ISO&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;date_created&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;date_available_on&amp;lt;/code&amp;gt; || datetime || Dates côté Stripe&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_facture&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fk_paiement&amp;lt;/code&amp;gt; || int || Facture et paiement Dolibarr résolus, si trouvés&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; || int || Ligne &amp;lt;code&amp;gt;llx_bank&amp;lt;/code&amp;gt; générée ''(vide pour un frais en mode TVA &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt;)''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;piece_num&amp;lt;/code&amp;gt; || varchar(20) || Numéro de pièce comptable généré, quand il y en a un&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt; || varchar(16) || &amp;lt;code&amp;gt;pending&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ignored&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;error_message&amp;lt;/code&amp;gt; || text || Détail en cas d'erreur&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;date_creation&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;date_processed&amp;lt;/code&amp;gt; || datetime || Horodatage technique&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_user_creat&amp;lt;/code&amp;gt; || int || Utilisateur ayant déclenché le traitement&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Clé unique''' sur &amp;lt;code&amp;gt;(stripe_object_id, entity)&amp;lt;/code&amp;gt; — c'est elle qui garantit qu'un même objet Stripe ne peut jamais être inséré deux fois, même en cas d'exécutions concurrentes.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;llx_stripeaccounting_log&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Colonne !! Rôle&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;level&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;DEBUG&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;INFO&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;WARNING&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;message&amp;lt;/code&amp;gt; || Message court&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;context&amp;lt;/code&amp;gt; || Contexte structuré en JSON&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_stripeaccounting_transaction&amp;lt;/code&amp;gt; || Transaction liée, si applicable&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;datec&amp;lt;/code&amp;gt; || Horodatage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 12. Dépannage ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:26%;&amp;quot; | Symptôme !! Cause probable !! Action&lt;br /&gt;
|-&lt;br /&gt;
| Le bouton « Synchroniser maintenant » est désactivé || Configuration minimale incomplète || Compléter les champs listés dans le bandeau d'alerte de la page de configuration&lt;br /&gt;
|-&lt;br /&gt;
| Une transaction reste en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; || Écriture refusée par Dolibarr (compte inexistant, période clôturée), ou remboursement non rattaché || Lire &amp;lt;code&amp;gt;error_message&amp;lt;/code&amp;gt; sur la ligne, puis le détail dans la table de logs&lt;br /&gt;
|-&lt;br /&gt;
| Le solde Stripe ne s'affiche pas || Clé API manquante ou invalide dans le module Stripe officiel || Vérifier &amp;lt;code&amp;gt;stripe/admin/stripe.php&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Un remboursement n'est jamais rapproché || Le paiement d'origine n'a pas été retrouvé via &amp;lt;code&amp;gt;ext_payment_id&amp;lt;/code&amp;gt; || Vérifier que le paiement Stripe a bien été enregistré par le module officiel avec cet identifiant&lt;br /&gt;
|-&lt;br /&gt;
| Un &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt; reste en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; || Tiers fournisseur Stripe non renseigné, ou sans code comptable fournisseur || Renseigner le champ en configuration, et compléter la fiche du tiers&lt;br /&gt;
|-&lt;br /&gt;
| Un remboursement importé en CSV reste en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; || '''Normal et attendu''' — ce compte n'est pas relié à &amp;lt;code&amp;gt;ext_payment_id&amp;lt;/code&amp;gt; || Traiter la facture et le remboursement manuellement en comptabilité&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 13. Pièges rencontrés ==&lt;br /&gt;
&lt;br /&gt;
Notes de développement, conservées pour éviter de retomber dedans.&lt;br /&gt;
&lt;br /&gt;
* '''&amp;lt;code&amp;gt;PaymentVarious::create()&amp;lt;/code&amp;gt;''' ne met à jour &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; qu'en base, jamais sur l'objet PHP. Un &amp;lt;code&amp;gt;fetch()&amp;lt;/code&amp;gt; après &amp;lt;code&amp;gt;create()&amp;lt;/code&amp;gt; est indispensable pour récupérer la vraie valeur.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;select_comptes()&amp;lt;/code&amp;gt;''' affiche son propre HTML ''et'' retourne le nombre de comptes. L'appeler en instruction nue : l'envelopper dans &amp;lt;code&amp;gt;print&amp;lt;/code&amp;gt; réafficherait ce nombre juste après la balise select.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;master.inc.php&amp;lt;/code&amp;gt;, pas &amp;lt;code&amp;gt;main.inc.php&amp;lt;/code&amp;gt;''' pour le script CLI. Le second attend une session HTTP et, en pur CLI, se termine silencieusement — aucune sortie, aucun log, code retour 0 — dans sa redirection vers la page de connexion. L'impression trompeuse que le script « ne fait rien » plutôt qu'une vraie erreur.&lt;br /&gt;
* '''Bibliothèques du cœur''' — &amp;lt;code&amp;gt;master.inc.php&amp;lt;/code&amp;gt; ne charge pas tout ce que &amp;lt;code&amp;gt;main.inc.php&amp;lt;/code&amp;gt; charge pour le web (par exemple &amp;lt;code&amp;gt;core/lib/date.lib.php&amp;lt;/code&amp;gt;, requis par &amp;lt;code&amp;gt;BookKeeping&amp;lt;/code&amp;gt;). À inclure explicitement si le script CLI évolue.&lt;br /&gt;
* '''Option « rien sélectionné » à &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;''' dans les sélecteurs de compte comptable — voir la section Configuration.&lt;br /&gt;
&lt;br /&gt;
== 14. Limites connues ==&lt;br /&gt;
&lt;br /&gt;
* '''Devises « zéro décimale »''' (JPY, KRW…) non gérées : les montants sont divisés par 100 en supposant deux décimales. Usage prévu : EUR.&lt;br /&gt;
* '''Fenêtre de 35 jours''' non configurable. Une synchronisation interrompue plus longtemps devra être rattrapée manuellement.&lt;br /&gt;
* '''Rattachement des remboursements''' — dépend de &amp;lt;code&amp;gt;ext_payment_id&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;ext_payment_site&amp;lt;/code&amp;gt; sur &amp;lt;code&amp;gt;llx_paiement&amp;lt;/code&amp;gt;, renseignés par le flux de paiement Stripe standard. Un paiement enregistré autrement ne pourra pas être rattaché automatiquement. Le rattachement se fait via le '''PaymentIntent id''', jamais via l'id de charge : le module Stripe du cœur ne stocke jamais ce dernier ''(il y met soit le PaymentIntent brut, soit un composite, selon le chemin de paiement emprunté)''.&lt;br /&gt;
* '''Import CSV en notation française''' uniquement : un export à point décimal ne serait pas interprété correctement.&lt;br /&gt;
* '''Colonne « Transfer » du CSV Paiements''' stockée à titre informatif seulement : elle ne sert pas à vérifier que le total des paiements correspond au montant du virement importé.&lt;br /&gt;
* '''Remboursements importés en CSV toujours en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;''' — comportement voulu, pas un bug.&lt;br /&gt;
* '''Mode TVA &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt;''' — le solde bancaire du compte Stripe ne reflète pas les frais, voir section 5.&lt;br /&gt;
&lt;br /&gt;
[[Catégorie:Dolibarr]]&lt;br /&gt;
[[Catégorie:Modules]]&lt;br /&gt;
[[Catégorie:Comptabilité]]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Stripeaccounting&amp;diff=551</id>
		<title>Stripeaccounting</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Stripeaccounting&amp;diff=551"/>
				<updated>2026-08-02T12:39:06Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:StripeAccounting — Documentation technique}}&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Us.png|64px|link=Stripeaccounting/en|Doc en anglais]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border:1px solid #c8ccd1; background:#f8f9fa; border-radius:4px; padding:1em 1.2em; margin:0 0 1.5em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''StripeAccounting''' est un module Dolibarr de '''rapprochement comptable Stripe'''.&lt;br /&gt;
&lt;br /&gt;
Il lit l'API Stripe (ou un export CSV), repère les mouvements que le module Stripe officiel ne comptabilise pas — frais, remboursements, litiges, virements — et pose les écritures manquantes.&lt;br /&gt;
&lt;br /&gt;
: '''Compatibilité''' — Dolibarr 17+, PHP 7.2 → 8.5&lt;br /&gt;
: '''Dépend de''' — modules Stripe, Banque, Comptabilité en partie double&lt;br /&gt;
: '''Voir aussi''' — [[README-fr|Installation et guide utilisateur]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== 1. Principes de fonctionnement ==&lt;br /&gt;
&lt;br /&gt;
Quatre règles gouvernent tout le module.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:22%;&amp;quot; | Principe !! Ce que ça veut dire&lt;br /&gt;
|-&lt;br /&gt;
| '''Complémentaire''' || Le module ne crée aucun paiement, aucune facture, aucun webhook. Il lit Stripe et complète la comptabilité, rien de plus.&lt;br /&gt;
|-&lt;br /&gt;
| '''Idempotent''' || Chaque objet Stripe n'est traité qu'une fois, quel que soit le nombre de relances de la synchronisation.&lt;br /&gt;
|-&lt;br /&gt;
| '''Jamais de devinette''' || Si une opération ne peut pas être rattachée avec certitude, rien n'est posté : la ligne passe en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; pour revue manuelle.&lt;br /&gt;
|-&lt;br /&gt;
| '''Configuration bloquante''' || Tant que la configuration minimale est incomplète, aucune synchronisation ne démarre (ni bouton, ni cron, ni import).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2. Prérequis ==&lt;br /&gt;
&lt;br /&gt;
=== Modules Dolibarr requis ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Module !! Ce qu'il apporte&lt;br /&gt;
|-&lt;br /&gt;
| '''Stripe''' (&amp;lt;code&amp;gt;modStripe&amp;lt;/code&amp;gt;) || Clé API, mode test/live, compte financier Stripe&lt;br /&gt;
|-&lt;br /&gt;
| '''Banque''' (&amp;lt;code&amp;gt;modBanque&amp;lt;/code&amp;gt;) || Tables &amp;lt;code&amp;gt;llx_bank&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;llx_bank_account&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| '''Comptabilité en partie double''' (&amp;lt;code&amp;gt;modAccounting&amp;lt;/code&amp;gt;) || Table &amp;lt;code&amp;gt;llx_accounting_bookkeeping&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Réglage Dolibarr indispensable ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ACCOUNTING_ACCOUNT_TRANSFER_CASH&amp;lt;/code&amp;gt; doit être renseigné dans '''Comptabilité → Configuration → Comptes par défaut'''. Sans lui, le virement interne généré par les payouts ne peut pas être transféré en comptabilité (limite de Dolibarr, pas du module).&lt;br /&gt;
&lt;br /&gt;
l’option s'appelle : '''Compte comptable par défaut pour les virements internes'''&lt;br /&gt;
&lt;br /&gt;
=== Notes ===&lt;br /&gt;
&lt;br /&gt;
* Le SDK PHP Stripe n'est pas dupliqué : le module réutilise la copie du cœur (&amp;lt;code&amp;gt;includes/stripe/stripe-php/&amp;lt;/code&amp;gt;).&lt;br /&gt;
* Le code évite volontairement toute syntaxe PHP postérieure à 7.2 (pas de &amp;lt;code&amp;gt;match&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;?-&amp;gt;&amp;lt;/code&amp;gt;, enums, propriétés typées, &amp;lt;code&amp;gt;str_contains&amp;lt;/code&amp;gt;…) pour couvrir toute la plage 7.2 → 8.5.&lt;br /&gt;
&lt;br /&gt;
== 3. Arborescence ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
custom/stripeaccounting/&lt;br /&gt;
├── core/modules/modStripeAccounting.class.php   Descripteur (droits, menus, cron, constantes)&lt;br /&gt;
├── class/&lt;br /&gt;
│   ├── StripeApi.class.php                      Wrapper SDK Stripe (lecture seule)&lt;br /&gt;
│   ├── StripeRepository.class.php               Accès SQL + idempotence&lt;br /&gt;
│   ├── StripeLogger.class.php                   Journalisation&lt;br /&gt;
│   ├── StripeAccounting.class.php               Génération des écritures&lt;br /&gt;
│   ├── StripePayout.class.php                   Rapprochement des virements&lt;br /&gt;
│   ├── StripeSync.class.php                     Orchestrateur (point d'entrée du cron)&lt;br /&gt;
│   ├── StripeCsvImporter.class.php              Import CSV&lt;br /&gt;
│   └── actions_stripeaccounting.class.php       Hook 'bankcard'&lt;br /&gt;
├── admin/setup.php                              Configuration&lt;br /&gt;
├── import.php                                   Import CSV&lt;br /&gt;
├── dashboard.php                                Tableau de bord&lt;br /&gt;
├── transaction_list.php                         Liste des transactions&lt;br /&gt;
├── cron/stripe_sync.php                         Point d'entrée CLI&lt;br /&gt;
├── lib/stripeaccounting.lib.php&lt;br /&gt;
├── sql/&lt;br /&gt;
├── langs/{fr_FR,en_US,es_ES,it_IT,de_DE}/&lt;br /&gt;
└── css/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sens des dépendances ===&lt;br /&gt;
&lt;br /&gt;
: pages et hook → &amp;lt;code&amp;gt;StripeSync&amp;lt;/code&amp;gt; → (&amp;lt;code&amp;gt;StripeApi&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StripeRepository&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StripeAccounting&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StripePayout&amp;lt;/code&amp;gt;) → &amp;lt;code&amp;gt;StripeLogger&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:26%;&amp;quot; | Classe !! Rôle&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeApi&amp;lt;/code&amp;gt; || Interroge le SDK Stripe (balance transactions, charges, remboursements, litiges, payouts) avec pagination automatique. Aucun accès base, aucune écriture.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeRepository&amp;lt;/code&amp;gt; || Tout le SQL des deux tables du module. &amp;lt;code&amp;gt;upsertTransaction()&amp;lt;/code&amp;gt; est le point d'idempotence.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeLogger&amp;lt;/code&amp;gt; || Écrit dans &amp;lt;code&amp;gt;llx_stripeaccounting_log&amp;lt;/code&amp;gt; et en miroir dans &amp;lt;code&amp;gt;dol_syslog()&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeAccounting&amp;lt;/code&amp;gt; || Construit les écritures (remboursement, litige, TVA autoliquidation) ou les mouvements bancaires (frais). Expose &amp;lt;code&amp;gt;checkConfig()&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripePayout&amp;lt;/code&amp;gt; || Crée le virement bancaire interne entre le compte Stripe et la banque réelle.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeSync&amp;lt;/code&amp;gt; || Orchestrateur : une méthode par flux, plus &amp;lt;code&amp;gt;reconcileStripeAccount()&amp;lt;/code&amp;gt; qui enchaîne tout.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeCsvImporter&amp;lt;/code&amp;gt; || Alimente le même pipeline depuis un export CSV Stripe.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ActionsStripeAccounting&amp;lt;/code&amp;gt; || Hook &amp;lt;code&amp;gt;bankcard&amp;lt;/code&amp;gt; : lien vers le tableau de bord sur la fiche du compte Stripe.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 4. Synchronisation et idempotence ==&lt;br /&gt;
&lt;br /&gt;
Chaque flux (&amp;lt;code&amp;gt;syncFees&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncRefunds&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncDisputes&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncPayouts&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncTransactions&amp;lt;/code&amp;gt;) suit toujours les mêmes étapes :&lt;br /&gt;
&lt;br /&gt;
# '''Vérifier la configuration''' — si elle est incomplète : log &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt;, arrêt immédiat, aucun appel API.&lt;br /&gt;
# '''Lister les objets Stripe''' sur une fenêtre glissante de '''35 jours'''.&lt;br /&gt;
# '''Filtrer''' — un objet est ignoré seulement s'il existe déjà ''et'' que son statut est &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;ignored&amp;lt;/code&amp;gt;. Une ligne en &amp;lt;code&amp;gt;pending&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; est '''retentée''' à ce run.&lt;br /&gt;
# '''Enregistrer''' en statut &amp;lt;code&amp;gt;pending&amp;lt;/code&amp;gt;, puis générer l'écriture ou le mouvement bancaire.&lt;br /&gt;
# '''Conclure''' — succès : statut &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt;. Échec : statut &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; avec le message, et '''le lot continue''' sur l'objet suivant.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #36c; background:#eaf3ff; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Reprise automatique''' — une ligne en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; redevient éligible au run suivant. Une fois la cause corrigée (par exemple un exercice comptable créé tardivement), aucune intervention manuelle n'est nécessaire.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi les doublons sont impossibles ===&lt;br /&gt;
&lt;br /&gt;
* '''Clé unique en base''' sur &amp;lt;code&amp;gt;(stripe_object_id, entity)&amp;lt;/code&amp;gt; — protège même contre deux exécutions concurrentes du cron.&lt;br /&gt;
* '''Test explicite avant traitement''' — évite jusqu'à la tentative d'écriture pour un objet déjà finalisé.&lt;br /&gt;
&lt;br /&gt;
=== Cas particuliers : &amp;lt;code&amp;gt;adjustment&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;payment_failure_refund&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Ce sont des corrections de solde effectuées par Stripe lui-même (réversion après litige, remboursement d'un paiement finalement échoué). Le module les '''enregistre''' — sinon elles resteraient invisibles — mais ne les comptabilise '''jamais''' automatiquement : le signe du montant et la cause varient trop. Elles sont créées directement en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, avec un message explicite, à traiter manuellement.&lt;br /&gt;
&lt;br /&gt;
== 5. Écritures comptables ==&lt;br /&gt;
&lt;br /&gt;
Toutes les lignes d'un même évènement partagent le triplet &amp;lt;code&amp;gt;doc_type='stripeaccounting'&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fk_doc&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;doc_ref&amp;lt;/code&amp;gt; : Dolibarr les regroupe automatiquement sous un même numéro de pièce, sans numérotation propre au module.&lt;br /&gt;
&lt;br /&gt;
=== Vue d'ensemble ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! Évènement !! Ce que fait le module !! Résultat comptable&lt;br /&gt;
|-&lt;br /&gt;
| Frais Stripe ''(TVA &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt;)'' || Mouvement bancaire &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; || Écriture 627xxx / 517xxx générée plus tard par Dolibarr&lt;br /&gt;
|-&lt;br /&gt;
| Frais Stripe ''(mode &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt;)'' || En plus : paire TVA postée immédiatement || Débit TVA déductible, crédit TVA autoliquidation ''(impact net nul)''&lt;br /&gt;
|-&lt;br /&gt;
| Frais Stripe ''(mode &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt;)'' || Écriture directe complète || Débit compte de frais HT + TVA déductible, crédit compte Stripe TTC&lt;br /&gt;
|-&lt;br /&gt;
| Frais d'abonnement / service ''(Radar, Billing, Connect…)'' || Mouvement bancaire &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; || Écriture générée plus tard par Dolibarr, sur le compte fournisseur Stripe&lt;br /&gt;
|-&lt;br /&gt;
| Virement (payout) || Virement bancaire interne entre les 2 comptes || Écriture générée plus tard par Dolibarr&lt;br /&gt;
|-&lt;br /&gt;
| Remboursement ''(facture retrouvée)'' || Écriture directe || Débit compte client 411xxx, crédit compte Stripe 517xxx&lt;br /&gt;
|-&lt;br /&gt;
| Remboursement ''(facture introuvable)'' || Rien || Statut &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, à traiter manuellement&lt;br /&gt;
|-&lt;br /&gt;
| Litige / chargeback || Écriture directe || Débit perte sur litiges 658xxx, crédit compte Stripe 517xxx ''(+ compte de frais si frais associés)''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi frais et virements ne génèrent pas d'écriture directe ===&lt;br /&gt;
&lt;br /&gt;
Le problème historique : quand une facture Stripe est transférée en comptabilité par le workflow standard de Dolibarr, le paiement est comptabilisé pour son montant '''brut''' — les frais sont ignorés à cette étape.&lt;br /&gt;
&lt;br /&gt;
Si le module postait ''en plus'' sa propre écriture ''et'' sa propre ligne bancaire, cette ligne resterait invisible pour &amp;lt;code&amp;gt;bankjournal.php&amp;lt;/code&amp;gt; — qui ne reconnaît que les lignes rattachées à &amp;lt;code&amp;gt;doc_type='bank'&amp;lt;/code&amp;gt;. Un administrateur transférant « normalement » le compte bancaire en comptabilité créait alors une '''seconde''' écriture pour le même mouvement.&lt;br /&gt;
&lt;br /&gt;
'''La solution retenue :''' pour les frais, les frais d'abonnement et les virements, le module ne crée plus que le '''mouvement bancaire réel''', avec les mécanismes natifs de Dolibarr. C'est ensuite le bouton natif ''« Transférer en comptabilité »'' qui produit l'écriture, comme pour n'importe quel autre mouvement bancaire. Le module ne touche donc plus du tout &amp;lt;code&amp;gt;llx_accounting_bookkeeping&amp;lt;/code&amp;gt; dans ces trois cas.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:22%;&amp;quot; | Cas !! Mécanisme natif utilisé&lt;br /&gt;
|-&lt;br /&gt;
| Frais et frais d'abonnement || &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; (mouvement bancaire avec compte de contrepartie, sans tiers ni facture), avec son propre &amp;lt;code&amp;gt;accountancy_code&amp;lt;/code&amp;gt; que &amp;lt;code&amp;gt;bankjournal.php&amp;lt;/code&amp;gt; lit directement.&lt;br /&gt;
|-&lt;br /&gt;
| Virements (payouts) || Virement interne Dolibarr : &amp;lt;code&amp;gt;Account::addline()&amp;lt;/code&amp;gt; des deux côtés, plus &amp;lt;code&amp;gt;add_url_line(…, 'banktransfert')&amp;lt;/code&amp;gt;. La contrepartie est imputée sur &amp;lt;code&amp;gt;ACCOUNTING_ACCOUNT_TRANSFER_CASH&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Dans les deux cas, le statut passe à &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt; — le module a fini son travail — mais '''&amp;lt;code&amp;gt;piece_num&amp;lt;/code&amp;gt; reste vide''' : l'écriture n'existe pas encore, seul &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; est renseigné. Après transfert manuel, on la retrouve avec &amp;lt;code&amp;gt;doc_type='bank'&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;fk_doc&amp;lt;/code&amp;gt; égal au &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; de la ligne.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #fc3; background:#fef6e7; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''À savoir''' — l'écriture des virements ne s'équilibre à zéro sur le compte de transfert que lorsque '''les deux''' comptes bancaires (Stripe ''et'' la banque réelle) ont été transférés en comptabilité, pas seulement un des deux.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #d33; background:#fee7e6; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''⚠ &amp;lt;code&amp;gt;STRIPE_AUTO_RECORD_PAYOUT&amp;lt;/code&amp;gt; doit rester désactivé'''&lt;br /&gt;
&lt;br /&gt;
Dès lors que ce module gère les virements, décochez « Activer l'enregistrement automatique des paiements Stripe » dans &amp;lt;code&amp;gt;stripe/admin/stripe.php&amp;lt;/code&amp;gt; — malgré son libellé, cette case ne concerne que les virements.&lt;br /&gt;
&lt;br /&gt;
Sinon, le webhook du module officiel et ce module créeraient chacun leur propre mouvement bancaire pour le même virement, sans le savoir l'un de l'autre.&lt;br /&gt;
&lt;br /&gt;
Le webhook cœur ne conserve d'ailleurs '''aucune''' trace de l'id du virement traité : en cas de double livraison Stripe (garantie « au moins une fois »), rien ne l'empêche de doublonner tout seul. Ce module, lui, a une vraie idempotence et rattrape automatiquement tout virement manqué sur 35 jours.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Page « Transferts Stripe » masquée ===&lt;br /&gt;
&lt;br /&gt;
À l'activation, &amp;lt;code&amp;gt;modStripeAccounting::init()&amp;lt;/code&amp;gt; désactive l'entrée de menu &amp;lt;code&amp;gt;stripe/payout.php&amp;lt;/code&amp;gt; : cette page interroge l'API en direct sans rien enregistrer, et sa coexistence avec ce module ne créerait qu'une confusion sur ce qui fait foi pour les virements. &amp;lt;code&amp;gt;remove()&amp;lt;/code&amp;gt; restaure la condition d'origine. '''C'est la seule table du cœur que ce module modifie''' — délibéré, et documenté ici pour cette raison.&lt;br /&gt;
&lt;br /&gt;
=== Frais par transaction ou frais d'abonnement ? ===&lt;br /&gt;
&lt;br /&gt;
Stripe facture deux choses distinctes sous le mot « frais » :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! !! Frais par transaction !! Frais d'abonnement / service&lt;br /&gt;
|-&lt;br /&gt;
! Exemple&lt;br /&gt;
| Commission sur chaque encaissement || Radar, Billing, Connect&lt;br /&gt;
|-&lt;br /&gt;
! Où le trouver&lt;br /&gt;
| Champ &amp;lt;code&amp;gt;.fee&amp;lt;/code&amp;gt; d'une balance transaction de type &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; || Balance transaction dédiée, de type &amp;lt;code&amp;gt;stripe_fee&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;application_fee&amp;lt;/code&amp;gt; ''(le &amp;lt;code&amp;gt;.fee&amp;lt;/code&amp;gt; y vaut toujours 0, le montant est dans &amp;lt;code&amp;gt;.amount&amp;lt;/code&amp;gt;)''&lt;br /&gt;
|-&lt;br /&gt;
! Compte utilisé&lt;br /&gt;
| Compte de frais configuré (627xxx) || Code comptable fournisseur du tiers Stripe configuré&lt;br /&gt;
|-&lt;br /&gt;
! Type en base&lt;br /&gt;
| &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Limite du mode TVA &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Ce mode doit scinder le montant TTC en HT + TVA, un découpage que &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; ne sait pas exprimer. Il reste donc sur l'ancien comportement : écriture directe complète, aucun mouvement bancaire créé. Pas de risque de doublon (puisque aucune ligne bancaire n'est produite), mais le solde &amp;lt;code&amp;gt;llx_bank&amp;lt;/code&amp;gt; du compte Stripe ne reflétera jamais les frais tant que ce mode est actif.&lt;br /&gt;
&lt;br /&gt;
== 6. Import CSV ==&lt;br /&gt;
&lt;br /&gt;
L'import couvre le cas d'un compte Stripe '''différent''' de celui configuré dans le module officiel — par exemple une autre boutique PrestaShop avec son propre compte marchand. L'API n'y a pas accès : le contenu est exporté en CSV depuis le dashboard Stripe, puis importé.&lt;br /&gt;
&lt;br /&gt;
=== Hypothèse de départ ===&lt;br /&gt;
&lt;br /&gt;
Les factures et paiements de cette boutique sont '''déjà''' comptabilisés dans Dolibarr par un autre processus, et l'encaissement (débit 517, crédit 411) est déjà posé. Seuls manquent les '''frais''', les '''remboursements''' et les '''virements''' — c'est exactement ce que l'import traite.&lt;br /&gt;
&lt;br /&gt;
=== Interface : un seul champ ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;import.php&amp;lt;/code&amp;gt; n'expose plus qu'un champ d'upload, '''Historique général''', câblé sur &amp;lt;code&amp;gt;importGeneralHistory()&amp;lt;/code&amp;gt;. Ce fichier couvre à lui seul tous les types de mouvements.&lt;br /&gt;
&lt;br /&gt;
Les méthodes &amp;lt;code&amp;gt;importPayments()&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;importPayouts()&amp;lt;/code&amp;gt; restent implémentées et fonctionnelles, mais ne sont plus atteignables depuis l'interface ; elles sont documentées ci-dessous pour mémoire.&lt;br /&gt;
&lt;br /&gt;
Comme le bouton « Synchroniser maintenant », l'import est bloqué — bandeau d'alerte, bouton désactivé, garde-fou côté serveur — tant que la configuration est incomplète.&lt;br /&gt;
&lt;br /&gt;
=== Les trois méthodes ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:24%;&amp;quot; | Méthode !! Export Stripe lu !! Traitement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;importGeneralHistory()&amp;lt;/code&amp;gt;&amp;lt;br /&amp;gt;''(seule exposée)'' || Balance history || Aiguillage par colonne &amp;lt;code&amp;gt;Type&amp;lt;/code&amp;gt;, voir tableau ci-dessous&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;importPayments()&amp;lt;/code&amp;gt; || Payments || Frais → écriture de frais. Montant remboursé → ligne &amp;lt;code&amp;gt;refund&amp;lt;/code&amp;gt; toujours en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;importPayouts()&amp;lt;/code&amp;gt; || Payouts || Exactement le même traitement qu'un payout venu de l'API&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Aiguillage de l'historique général, par colonne &amp;lt;code&amp;gt;Type&amp;lt;/code&amp;gt; :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:30%;&amp;quot; | Type Stripe !! Traitement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt; || Virement bancaire interne, comme via l'API&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;payment&amp;lt;/code&amp;gt; avec frais || Mouvement de frais&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_fee&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;application_fee&amp;lt;/code&amp;gt; || Frais d'abonnement, sur le compte fournisseur Stripe&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;refund&amp;lt;/code&amp;gt; || Enregistré, '''toujours''' en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;payout_minimum_balance_hold&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;…_release&amp;lt;/code&amp;gt; || '''Ignorés''' — réserve glissante Stripe, impact net nul, rien à comptabiliser&lt;br /&gt;
|-&lt;br /&gt;
| tout autre type || Enregistré en &amp;lt;code&amp;gt;type='other'&amp;lt;/code&amp;gt;, statut &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, type brut conservé dans la description. Aucune écriture devinée.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les colonnes sont reconnues '''par leur nom''' : l'ordre importe peu, et les colonnes en plus non utilisées sont ignorées.&lt;br /&gt;
&lt;br /&gt;
=== Idempotence de l'import ===&lt;br /&gt;
&lt;br /&gt;
La clé unique protège contre tout double import : réimporter le même CSV, ou un CSV qui chevauche un import précédent, ne crée aucun doublon.&lt;br /&gt;
&lt;br /&gt;
Point important : dans l'historique général, les lignes &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;payment&amp;lt;/code&amp;gt; sont indexées par leur colonne '''&amp;lt;code&amp;gt;Source&amp;lt;/code&amp;gt;''' (&amp;lt;code&amp;gt;po_…&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ch_…&amp;lt;/code&amp;gt;), pas par l'&amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt; de la ligne (&amp;lt;code&amp;gt;txn_…&amp;lt;/code&amp;gt;) — soit exactement la même clé que les imports dédiés. Importer l'historique général '''en plus''' des exports spécifiques ne poste donc jamais deux fois la même écriture, quel que soit l'ordre.&lt;br /&gt;
&lt;br /&gt;
Les identifiants Stripe étant uniques à l'échelle de la plateforme, mélanger dans la même table des lignes venant du compte API et de plusieurs comptes importés en CSV ne présente aucun risque de collision.&lt;br /&gt;
&lt;br /&gt;
=== Détails pratiques ===&lt;br /&gt;
&lt;br /&gt;
* '''Libellé source''' — un champ libre saisi à l'import (ex. « Boutique DRM ») est stocké sur chaque ligne créée et sert de colonne et de filtre dans la liste, pour distinguer plusieurs boutiques côte à côte.&lt;br /&gt;
* '''Format des montants''' — les CSV Stripe utilisent la virgule décimale française, convertie via &amp;lt;code&amp;gt;price2num()&amp;lt;/code&amp;gt;. Les dates marquées &amp;lt;code&amp;gt;(UTC)&amp;lt;/code&amp;gt; sont interprétées comme telles.&lt;br /&gt;
&lt;br /&gt;
== 7. Configuration ==&lt;br /&gt;
&lt;br /&gt;
La clé API et le mode test/live ne sont '''pas''' ressaisis ici : ils sont lus en lecture seule depuis le module Stripe officiel.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:26%;&amp;quot; | Champ !! Constante !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| Compte financier Stripe || &amp;lt;code&amp;gt;STRIPE_BANK_ACCOUNT_FOR_PAYMENTS&amp;lt;/code&amp;gt; ''(constante du module officiel)'' || Sélecteur de compte bancaire. Aucune copie locale, donc aucun risque de divergence.&lt;br /&gt;
|-&lt;br /&gt;
| Compte bancaire principal || &amp;lt;code&amp;gt;STRIPE_BANK_ACCOUNT_FOR_BANKTRANSFERS&amp;lt;/code&amp;gt; ''(constante du module officiel)'' || Même sélecteur. Voir l'encadré ci-dessous.&lt;br /&gt;
|-&lt;br /&gt;
| Compte de frais || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_FRAIS&amp;lt;/code&amp;gt; || Numéro de compte, ex. 627xxx&lt;br /&gt;
|-&lt;br /&gt;
| Compte de litiges || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_LITIGES&amp;lt;/code&amp;gt; || Numéro de compte, ex. 658xxx. '''Requis''' — utilisé dès qu'un litige survient, quel que soit le mode TVA.&lt;br /&gt;
|-&lt;br /&gt;
| Tiers fournisseur Stripe || &amp;lt;code&amp;gt;STRIPEACCOUNTING_FOURNISSEUR_STRIPE_ID&amp;lt;/code&amp;gt; || Tiers marqué fournisseur ; c'est son code comptable fournisseur qui est utilisé. Optionnel, sauf s'il existe des frais d'abonnement.&lt;br /&gt;
|-&lt;br /&gt;
| Mode TVA || &amp;lt;code&amp;gt;STRIPEACCOUNTING_VAT_MODE&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Compte TVA déductible (intracommunautaire) || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_TVA_DEDUCTIBLE&amp;lt;/code&amp;gt; || Requis si mode TVA ≠ &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt;. Stripe facturant toujours depuis une entité UE non française, la TVA déductible est intracommunautaire dans tous les cas.&lt;br /&gt;
|-&lt;br /&gt;
| Compte de TVA due (intracommunautaire) || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_TVA_AUTOLIQUIDATION&amp;lt;/code&amp;gt; || Requis en mode &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt; uniquement — jamais utilisé en mode &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| Taux de TVA || &amp;lt;code&amp;gt;STRIPEACCOUNTING_VAT_RATE&amp;lt;/code&amp;gt; || Pourcentage, 20 par défaut&lt;br /&gt;
|-&lt;br /&gt;
| Fréquence de synchronisation || &amp;lt;code&amp;gt;STRIPEACCOUNTING_SYNC_UNITFREQUENCY&amp;lt;/code&amp;gt; || Répercutée sur la tâche planifiée (en secondes)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #36c; background:#eaf3ff; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Pourquoi redéfinir le compte bancaire principal ici ?'''&lt;br /&gt;
&lt;br /&gt;
La page de configuration du module Stripe officiel n'affiche ce champ que si &amp;lt;code&amp;gt;STRIPE_AUTO_RECORD_PAYOUT&amp;lt;/code&amp;gt; est activé — et son handler de sauvegarde remet la valeur à 0 à chaque enregistrement tant que le champ n'est pas rendu. Or ce réglage doit justement rester désactivé quand ce module gère les virements. Le champ est donc réexposé ici, en écrivant directement la constante du cœur, pour que la valeur reste configurable et stable.&lt;br /&gt;
&lt;br /&gt;
Les deux sélecteurs de compte n'écrivent leur constante que si un compte réel a été soumis : enregistrer la page pour un tout autre champ n'écrase jamais une valeur correcte.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Vérification de la configuration ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;StripeAccounting::checkConfig()&amp;lt;/code&amp;gt; renvoie la liste des constantes manquantes. Elle est appelée à la fois par la page de configuration (bandeau d'information) et par chaque point d'entrée de synchronisation (garde-fou réel qui bloque tout traitement).&lt;br /&gt;
&lt;br /&gt;
=== Piège des sélecteurs de compte comptable ===&lt;br /&gt;
&lt;br /&gt;
Les quatre champs utilisant &amp;lt;code&amp;gt;FormAccounting::select_account()&amp;lt;/code&amp;gt; (frais, litiges, les deux comptes TVA) ont une option « rien sélectionné » dont la valeur est '''&amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;''' — une chaîne non vide, donc vraie en PHP. Un champ laissé vide et enregistré stocke littéralement &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;StripeAccounting::getAccountConst()&amp;lt;/code&amp;gt; normalise cette valeur en chaîne vide à la lecture, partout où ces constantes sont lues. Aucune écriture ne peut donc atterrir sur le compte inexistant &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 8. Interface ==&lt;br /&gt;
&lt;br /&gt;
=== Tableau de bord ===&lt;br /&gt;
&lt;br /&gt;
Solde Stripe (appel API en direct), nombre de transactions non rapprochées, total des frais du mois, payouts en attente, et bouton '''Synchroniser maintenant''' — désactivé, avec bandeau listant les constantes manquantes, tant que la configuration est incomplète.&lt;br /&gt;
&lt;br /&gt;
=== Liste des transactions ===&lt;br /&gt;
&lt;br /&gt;
Liste paginée, triable et filtrable, construite avec le même mécanisme que les listes natives Dolibarr : l'icône en haut à droite du tableau permet à chaque utilisateur de choisir ses colonnes, et la préférence est mémorisée par utilisateur.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:20%;&amp;quot; | Colonne !! Contenu&lt;br /&gt;
|-&lt;br /&gt;
| Montant, Frais, Total || Le popup sur les frais indique la TVA sur frais quand une paire d'autoliquidation ou une TVA française a été postée&lt;br /&gt;
|-&lt;br /&gt;
| Type, Description || Popup avec l'ID Stripe, l'ID d'évènement ou de source, et la description complète non tronquée&lt;br /&gt;
|-&lt;br /&gt;
| Tiers || Le client résolu via la facture, ou via la charge source pour son frais associé, ou le tiers fournisseur Stripe pour un frais d'abonnement&lt;br /&gt;
|-&lt;br /&gt;
| Écriture || Lien « Pièce n°X » vers l'écriture, et/ou lien vers le mouvement bancaire associé — voir la nuance ci-dessous&lt;br /&gt;
|-&lt;br /&gt;
| Source, Statut || Le badge &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; ouvre un popup avec le message d'erreur complet : plus besoin d'aller en base pour comprendre un échec&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #fc3; background:#fef6e7; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Lire la colonne « Écriture »''' — sur une ligne &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt;, le lien pointe vers le '''mouvement bancaire''', pas vers une pièce comptable. Le &amp;lt;code&amp;gt;piece_num&amp;lt;/code&amp;gt; du module, lui, n'est jamais l'écriture 627/517 du frais : c'est uniquement la paire TVA d'autoliquidation. L'écriture du frais est générée plus tard, par le bouton natif de Dolibarr, et n'est jamais reportée sur cette ligne.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La page est '''purement consultative''' : aucune comptabilisation manuelle n'y est proposée. Le module comptabilise automatiquement, et le transfert en comptabilité des frais et virements se fait depuis le bouton natif « Transférer en comptabilité ».&lt;br /&gt;
&lt;br /&gt;
=== Lignes &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Chaque paiement produit '''deux lignes''' en base :&lt;br /&gt;
&lt;br /&gt;
* une ligne &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt;, toujours en statut &amp;lt;code&amp;gt;ignored&amp;lt;/code&amp;gt;, frais à 0, jamais traitée — présente uniquement pour l'idempotence ;&lt;br /&gt;
* une ligne &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; pour le même paiement, liée à la première.&lt;br /&gt;
&lt;br /&gt;
Les deux apparaissent séparément dans la liste, mais la ligne &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; porte elle aussi le lien vers le paiement et la facture, résolu par jointure.&lt;br /&gt;
&lt;br /&gt;
=== Bandeau mode test ===&lt;br /&gt;
&lt;br /&gt;
Tant que le mode live n'est pas activé, le tableau de bord, la page de configuration et la liste des transactions affichent tous les trois le même avertissement que le module Stripe officiel. Impossible d'oublier qu'on travaille en mode test.&lt;br /&gt;
&lt;br /&gt;
=== Menus ===&lt;br /&gt;
&lt;br /&gt;
Tout est regroupé sous '''Banques et caisses → Compte Stripe''' (menu du module officiel), à plat, en trois entrées de même niveau :&lt;br /&gt;
&lt;br /&gt;
# Tableau de bord Stripe&lt;br /&gt;
# Transactions Stripe&lt;br /&gt;
# Import CSV ''(réservé aux administrateurs)''&lt;br /&gt;
&lt;br /&gt;
Un lien vers le tableau de bord est aussi ajouté automatiquement sur la fiche du compte bancaire configuré comme compte Stripe.&lt;br /&gt;
&lt;br /&gt;
== 9. Tâche planifiée ==&lt;br /&gt;
&lt;br /&gt;
Deux façons d'exécuter la synchronisation, toutes deux idempotentes et sans risque à relancer. Dans les deux cas le code exécuté est strictement le même : aucune divergence de comportement.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #d33; background:#fee7e6; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''⚠ Aucune des deux ne démarre toute seule.'''&lt;br /&gt;
&lt;br /&gt;
L'activation du module crée la tâche &amp;lt;code&amp;gt;StripeAccountingSync&amp;lt;/code&amp;gt;, mais '''désactivée par défaut'''. Et même activée, l'ordonnanceur Dolibarr n'est déclenché par rien tant qu'aucune crontab système ne l'appelle. Sans ces deux étapes, la synchro n'a lieu qu'au clic manuel sur « Synchroniser maintenant ».&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Étape 1 — activer la tâche ===&lt;br /&gt;
&lt;br /&gt;
Dans '''Accueil → Configuration → Modules → Tâches planifiées'''. &amp;lt;code&amp;gt;llx_cronjob&amp;lt;/code&amp;gt; étant une table du cœur, ce réglage se fait uniquement par l'interface, jamais en SQL direct depuis le module.&lt;br /&gt;
&lt;br /&gt;
=== Étape 2 — un déclencheur système ===&lt;br /&gt;
&lt;br /&gt;
Au choix, l'une des deux options.&lt;br /&gt;
&lt;br /&gt;
'''Option A — ordonnanceur Dolibarr''' ''(recommandé si plusieurs tâches planifiées coexistent)''. Lance toutes les tâches dues, pas seulement celle-ci. Nécessite l'étape 1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
*/15 * * * * curl &amp;quot;https://votre-dolibarr/public/cron/cron_run_jobs_by_url.php?securitykey=VOTRE_CLE&amp;amp;userlogin=VOTRE_LOGIN&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La clé de sécurité se génère sur la page des tâches planifiées, bouton « Sécurité de l'exécution des tâches par URL ».&lt;br /&gt;
&lt;br /&gt;
'''Option B — script CLI du module.''' Autonome, refuse l'exécution depuis un navigateur, et indépendant de l'état activé ou non de la tâche Dolibarr.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
*/15 * * * * php /chemin/vers/htdocs/custom/stripeaccounting/cron/stripe_sync.php &amp;gt;&amp;gt; /var/log/stripeaccounting.log 2&amp;gt;&amp;amp;1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 10. Journalisation et permissions ==&lt;br /&gt;
&lt;br /&gt;
=== Journalisation ===&lt;br /&gt;
&lt;br /&gt;
Chaque appel API, écriture générée, avertissement ou erreur est tracé dans &amp;lt;code&amp;gt;llx_stripeaccounting_log&amp;lt;/code&amp;gt;, consultable en base ou via le fichier de log standard Dolibarr. Niveaux : &amp;lt;code&amp;gt;DEBUG&amp;lt;/code&amp;gt; &amp;lt; &amp;lt;code&amp;gt;INFO&amp;lt;/code&amp;gt; &amp;lt; &amp;lt;code&amp;gt;WARNING&amp;lt;/code&amp;gt; &amp;lt; &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt;. La colonne &amp;lt;code&amp;gt;context&amp;lt;/code&amp;gt; contient le détail structuré en JSON (payload API, montants calculés…).&lt;br /&gt;
&lt;br /&gt;
=== Permissions ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Droit !! Contrôle&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;read&amp;lt;/code&amp;gt; || Consultation du tableau de bord et de la liste&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;write&amp;lt;/code&amp;gt; || Déclarée pour la configuration, mais non vérifiée dans le code aujourd'hui&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;reconcile&amp;lt;/code&amp;gt; || Déclenchement manuel de la synchronisation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
En pratique, &amp;lt;code&amp;gt;admin/setup.php&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;import.php&amp;lt;/code&amp;gt; ne contrôlent que le statut '''administrateur Dolibarr''', pas le droit &amp;lt;code&amp;gt;write&amp;lt;/code&amp;gt; : seuls les administrateurs peuvent configurer le module ou importer un CSV, quoi qu'il soit coché dans les permissions.&lt;br /&gt;
&lt;br /&gt;
== 11. Base de données ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;llx_stripeaccounting_transaction&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Une ligne par objet Stripe traité — charge, frais, remboursement, litige ou virement — tous dans la même table, distingués par la colonne &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:24%;&amp;quot; | Colonne !! style=&amp;quot;width:16%;&amp;quot; | Type !! Rôle&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rowid&amp;lt;/code&amp;gt; || int AI || Clé primaire&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;entity&amp;lt;/code&amp;gt; || int || Multi-société Dolibarr&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_object_id&amp;lt;/code&amp;gt; || varchar(80) || Identifiant Stripe — '''ancre d'idempotence'''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_event_id&amp;lt;/code&amp;gt; || varchar(80) || Identifiant d'évènement, informatif seulement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt; || varchar(20) || &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;refund&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;dispute&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;other&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_source_id&amp;lt;/code&amp;gt; || varchar(80) || Objet Stripe source (ex. la charge liée à un remboursement)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;source_label&amp;lt;/code&amp;gt; || varchar(80) || Libellé libre saisi à l'import CSV ; vide pour les lignes venues de l'API&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;description&amp;lt;/code&amp;gt; || varchar(255) || Libellé Stripe&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;amount&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;net&amp;lt;/code&amp;gt; || decimal(24,8) || Montants déjà convertis depuis les centimes Stripe&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;currency&amp;lt;/code&amp;gt; || varchar(3) || Code devise ISO&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;date_created&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;date_available_on&amp;lt;/code&amp;gt; || datetime || Dates côté Stripe&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_facture&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fk_paiement&amp;lt;/code&amp;gt; || int || Facture et paiement Dolibarr résolus, si trouvés&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; || int || Ligne &amp;lt;code&amp;gt;llx_bank&amp;lt;/code&amp;gt; générée ''(vide pour un frais en mode TVA &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt;)''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;piece_num&amp;lt;/code&amp;gt; || varchar(20) || Numéro de pièce comptable généré, quand il y en a un&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt; || varchar(16) || &amp;lt;code&amp;gt;pending&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ignored&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;error_message&amp;lt;/code&amp;gt; || text || Détail en cas d'erreur&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;date_creation&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;date_processed&amp;lt;/code&amp;gt; || datetime || Horodatage technique&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_user_creat&amp;lt;/code&amp;gt; || int || Utilisateur ayant déclenché le traitement&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Clé unique''' sur &amp;lt;code&amp;gt;(stripe_object_id, entity)&amp;lt;/code&amp;gt; — c'est elle qui garantit qu'un même objet Stripe ne peut jamais être inséré deux fois, même en cas d'exécutions concurrentes.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;llx_stripeaccounting_log&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Colonne !! Rôle&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;level&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;DEBUG&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;INFO&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;WARNING&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;message&amp;lt;/code&amp;gt; || Message court&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;context&amp;lt;/code&amp;gt; || Contexte structuré en JSON&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_stripeaccounting_transaction&amp;lt;/code&amp;gt; || Transaction liée, si applicable&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;datec&amp;lt;/code&amp;gt; || Horodatage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 12. Dépannage ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:26%;&amp;quot; | Symptôme !! Cause probable !! Action&lt;br /&gt;
|-&lt;br /&gt;
| Le bouton « Synchroniser maintenant » est désactivé || Configuration minimale incomplète || Compléter les champs listés dans le bandeau d'alerte de la page de configuration&lt;br /&gt;
|-&lt;br /&gt;
| Une transaction reste en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; || Écriture refusée par Dolibarr (compte inexistant, période clôturée), ou remboursement non rattaché || Lire &amp;lt;code&amp;gt;error_message&amp;lt;/code&amp;gt; sur la ligne, puis le détail dans la table de logs&lt;br /&gt;
|-&lt;br /&gt;
| Le solde Stripe ne s'affiche pas || Clé API manquante ou invalide dans le module Stripe officiel || Vérifier &amp;lt;code&amp;gt;stripe/admin/stripe.php&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Un remboursement n'est jamais rapproché || Le paiement d'origine n'a pas été retrouvé via &amp;lt;code&amp;gt;ext_payment_id&amp;lt;/code&amp;gt; || Vérifier que le paiement Stripe a bien été enregistré par le module officiel avec cet identifiant&lt;br /&gt;
|-&lt;br /&gt;
| Un &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt; reste en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; || Tiers fournisseur Stripe non renseigné, ou sans code comptable fournisseur || Renseigner le champ en configuration, et compléter la fiche du tiers&lt;br /&gt;
|-&lt;br /&gt;
| Un remboursement importé en CSV reste en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; || '''Normal et attendu''' — ce compte n'est pas relié à &amp;lt;code&amp;gt;ext_payment_id&amp;lt;/code&amp;gt; || Traiter la facture et le remboursement manuellement en comptabilité&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 13. Pièges rencontrés ==&lt;br /&gt;
&lt;br /&gt;
Notes de développement, conservées pour éviter de retomber dedans.&lt;br /&gt;
&lt;br /&gt;
* '''&amp;lt;code&amp;gt;PaymentVarious::create()&amp;lt;/code&amp;gt;''' ne met à jour &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; qu'en base, jamais sur l'objet PHP. Un &amp;lt;code&amp;gt;fetch()&amp;lt;/code&amp;gt; après &amp;lt;code&amp;gt;create()&amp;lt;/code&amp;gt; est indispensable pour récupérer la vraie valeur.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;select_comptes()&amp;lt;/code&amp;gt;''' affiche son propre HTML ''et'' retourne le nombre de comptes. L'appeler en instruction nue : l'envelopper dans &amp;lt;code&amp;gt;print&amp;lt;/code&amp;gt; réafficherait ce nombre juste après la balise select.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;master.inc.php&amp;lt;/code&amp;gt;, pas &amp;lt;code&amp;gt;main.inc.php&amp;lt;/code&amp;gt;''' pour le script CLI. Le second attend une session HTTP et, en pur CLI, se termine silencieusement — aucune sortie, aucun log, code retour 0 — dans sa redirection vers la page de connexion. L'impression trompeuse que le script « ne fait rien » plutôt qu'une vraie erreur.&lt;br /&gt;
* '''Bibliothèques du cœur''' — &amp;lt;code&amp;gt;master.inc.php&amp;lt;/code&amp;gt; ne charge pas tout ce que &amp;lt;code&amp;gt;main.inc.php&amp;lt;/code&amp;gt; charge pour le web (par exemple &amp;lt;code&amp;gt;core/lib/date.lib.php&amp;lt;/code&amp;gt;, requis par &amp;lt;code&amp;gt;BookKeeping&amp;lt;/code&amp;gt;). À inclure explicitement si le script CLI évolue.&lt;br /&gt;
* '''Option « rien sélectionné » à &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;''' dans les sélecteurs de compte comptable — voir la section Configuration.&lt;br /&gt;
&lt;br /&gt;
== 14. Limites connues ==&lt;br /&gt;
&lt;br /&gt;
* '''Devises « zéro décimale »''' (JPY, KRW…) non gérées : les montants sont divisés par 100 en supposant deux décimales. Usage prévu : EUR.&lt;br /&gt;
* '''Fenêtre de 35 jours''' non configurable. Une synchronisation interrompue plus longtemps devra être rattrapée manuellement.&lt;br /&gt;
* '''Rattachement des remboursements''' — dépend de &amp;lt;code&amp;gt;ext_payment_id&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;ext_payment_site&amp;lt;/code&amp;gt; sur &amp;lt;code&amp;gt;llx_paiement&amp;lt;/code&amp;gt;, renseignés par le flux de paiement Stripe standard. Un paiement enregistré autrement ne pourra pas être rattaché automatiquement. Le rattachement se fait via le '''PaymentIntent id''', jamais via l'id de charge : le module Stripe du cœur ne stocke jamais ce dernier ''(il y met soit le PaymentIntent brut, soit un composite, selon le chemin de paiement emprunté)''.&lt;br /&gt;
* '''Import CSV en notation française''' uniquement : un export à point décimal ne serait pas interprété correctement.&lt;br /&gt;
* '''Colonne « Transfer » du CSV Paiements''' stockée à titre informatif seulement : elle ne sert pas à vérifier que le total des paiements correspond au montant du virement importé.&lt;br /&gt;
* '''Remboursements importés en CSV toujours en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;''' — comportement voulu, pas un bug.&lt;br /&gt;
* '''Mode TVA &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt;''' — le solde bancaire du compte Stripe ne reflète pas les frais, voir section 5.&lt;br /&gt;
&lt;br /&gt;
[[Catégorie:Dolibarr]]&lt;br /&gt;
[[Catégorie:Modules]]&lt;br /&gt;
[[Catégorie:Comptabilité]]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Stripeaccounting/en&amp;diff=550</id>
		<title>Stripeaccounting/en</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Stripeaccounting/en&amp;diff=550"/>
				<updated>2026-08-02T12:36:37Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:StripeAccounting — Technical documentation}}&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Fr.png|link=Stripeaccounting]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border:1px solid #c8ccd1; background:#f8f9fa; border-radius:4px; padding:1em 1.2em; margin:0 0 1.5em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''StripeAccounting''' is a Dolibarr module for '''Stripe accounting reconciliation'''.&lt;br /&gt;
&lt;br /&gt;
It reads the Stripe API (or a CSV export), identifies the movements the official Stripe module does not post — fees, refunds, disputes, payouts — and creates the missing accounting entries.&lt;br /&gt;
&lt;br /&gt;
: '''Compatibility''' — Dolibarr 17+, PHP 7.2 → 8.5&lt;br /&gt;
: '''Depends on''' — Stripe, Bank and Double-entry Accounting modules&lt;br /&gt;
: '''See also''' — [[README|Installation and user guide]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== 1. Design principles ==&lt;br /&gt;
&lt;br /&gt;
Four rules govern the whole module.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:22%;&amp;quot; | Principle !! What it means&lt;br /&gt;
|-&lt;br /&gt;
| '''Complementary''' || The module creates no payment, no invoice, no webhook. It reads Stripe and completes the books, nothing more.&lt;br /&gt;
|-&lt;br /&gt;
| '''Idempotent''' || Each Stripe object is processed once only, no matter how many times the sync is re-run.&lt;br /&gt;
|-&lt;br /&gt;
| '''Never guess''' || If an operation cannot be matched with certainty, nothing is posted: the row goes to &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; for manual review.&lt;br /&gt;
|-&lt;br /&gt;
| '''Configuration is blocking''' || As long as the minimum configuration is incomplete, no sync runs at all (no button, no cron, no import).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2. Requirements ==&lt;br /&gt;
&lt;br /&gt;
=== Required Dolibarr modules ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Module !! What it provides&lt;br /&gt;
|-&lt;br /&gt;
| '''Stripe''' (&amp;lt;code&amp;gt;modStripe&amp;lt;/code&amp;gt;) || API key, test/live mode, Stripe financial account&lt;br /&gt;
|-&lt;br /&gt;
| '''Bank''' (&amp;lt;code&amp;gt;modBanque&amp;lt;/code&amp;gt;) || &amp;lt;code&amp;gt;llx_bank&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;llx_bank_account&amp;lt;/code&amp;gt; tables&lt;br /&gt;
|-&lt;br /&gt;
| '''Double-entry accounting''' (&amp;lt;code&amp;gt;modAccounting&amp;lt;/code&amp;gt;) || &amp;lt;code&amp;gt;llx_accounting_bookkeeping&amp;lt;/code&amp;gt; table&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Mandatory Dolibarr setting ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ACCOUNTING_ACCOUNT_TRANSFER_CASH&amp;lt;/code&amp;gt; must be set under '''Accounting → Setup → Miscellaneous accounts'''. Without it, the internal transfer generated by payouts cannot be transferred to accounting (a Dolibarr limitation, not a module one).&lt;br /&gt;
&lt;br /&gt;
=== Notes ===&lt;br /&gt;
&lt;br /&gt;
* The Stripe PHP SDK is not re-vendored: the module reuses the core copy (&amp;lt;code&amp;gt;includes/stripe/stripe-php/&amp;lt;/code&amp;gt;).&lt;br /&gt;
* The code deliberately avoids any PHP syntax newer than 7.2 (no &amp;lt;code&amp;gt;match&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;?-&amp;gt;&amp;lt;/code&amp;gt;, enums, typed properties, &amp;lt;code&amp;gt;str_contains&amp;lt;/code&amp;gt;…) so it runs across the whole 7.2 → 8.5 range.&lt;br /&gt;
&lt;br /&gt;
== 3. File tree ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
custom/stripeaccounting/&lt;br /&gt;
├── core/modules/modStripeAccounting.class.php   Module descriptor (permissions, menus, cron, constants)&lt;br /&gt;
├── class/&lt;br /&gt;
│   ├── StripeApi.class.php                      Stripe SDK wrapper (read-only)&lt;br /&gt;
│   ├── StripeRepository.class.php               SQL access + idempotency&lt;br /&gt;
│   ├── StripeLogger.class.php                   Logging&lt;br /&gt;
│   ├── StripeAccounting.class.php               Accounting entry generation&lt;br /&gt;
│   ├── StripePayout.class.php                   Payout reconciliation&lt;br /&gt;
│   ├── StripeSync.class.php                     Orchestrator (cron entry point)&lt;br /&gt;
│   ├── StripeCsvImporter.class.php              CSV import&lt;br /&gt;
│   └── actions_stripeaccounting.class.php       'bankcard' hook&lt;br /&gt;
├── admin/setup.php                              Configuration&lt;br /&gt;
├── import.php                                   CSV import&lt;br /&gt;
├── dashboard.php                                Dashboard&lt;br /&gt;
├── transaction_list.php                         Transaction list&lt;br /&gt;
├── cron/stripe_sync.php                         CLI entry point&lt;br /&gt;
├── lib/stripeaccounting.lib.php&lt;br /&gt;
├── sql/&lt;br /&gt;
├── langs/{fr_FR,en_US,es_ES,it_IT,de_DE}/&lt;br /&gt;
└── css/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dependency direction ===&lt;br /&gt;
&lt;br /&gt;
: pages and hook → &amp;lt;code&amp;gt;StripeSync&amp;lt;/code&amp;gt; → (&amp;lt;code&amp;gt;StripeApi&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StripeRepository&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StripeAccounting&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StripePayout&amp;lt;/code&amp;gt;) → &amp;lt;code&amp;gt;StripeLogger&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:26%;&amp;quot; | Class !! Role&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeApi&amp;lt;/code&amp;gt; || Queries the Stripe SDK (balance transactions, charges, refunds, disputes, payouts) with automatic pagination. No database access, no accounting entries.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeRepository&amp;lt;/code&amp;gt; || All SQL for the module's two tables. &amp;lt;code&amp;gt;upsertTransaction()&amp;lt;/code&amp;gt; is the idempotency anchor.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeLogger&amp;lt;/code&amp;gt; || Writes to &amp;lt;code&amp;gt;llx_stripeaccounting_log&amp;lt;/code&amp;gt; and mirrors to &amp;lt;code&amp;gt;dol_syslog()&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeAccounting&amp;lt;/code&amp;gt; || Builds accounting entries (refund, dispute, reverse-charge VAT) or bank movements (fees). Exposes &amp;lt;code&amp;gt;checkConfig()&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripePayout&amp;lt;/code&amp;gt; || Creates the internal bank transfer between the Stripe account and the real bank account.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeSync&amp;lt;/code&amp;gt; || Orchestrator: one method per flow, plus &amp;lt;code&amp;gt;reconcileStripeAccount()&amp;lt;/code&amp;gt; which chains them all.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeCsvImporter&amp;lt;/code&amp;gt; || Feeds the same pipeline from a Stripe CSV export.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ActionsStripeAccounting&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;bankcard&amp;lt;/code&amp;gt; hook: dashboard link on the Stripe account record.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 4. Synchronisation and idempotency ==&lt;br /&gt;
&lt;br /&gt;
Every flow (&amp;lt;code&amp;gt;syncFees&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncRefunds&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncDisputes&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncPayouts&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncTransactions&amp;lt;/code&amp;gt;) always follows the same steps:&lt;br /&gt;
&lt;br /&gt;
# '''Check the configuration''' — if incomplete: &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt; log, immediate stop, no API call at all.&lt;br /&gt;
# '''List Stripe objects''' over a rolling window of '''35 days'''.&lt;br /&gt;
# '''Filter''' — an object is skipped only if it already exists ''and'' its status is &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;ignored&amp;lt;/code&amp;gt;. A row in &amp;lt;code&amp;gt;pending&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; is '''retried''' on this run.&lt;br /&gt;
# '''Record''' it as &amp;lt;code&amp;gt;pending&amp;lt;/code&amp;gt;, then generate the accounting entry or bank movement.&lt;br /&gt;
# '''Conclude''' — success: status &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt;. Failure: status &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; with the message, and '''the batch carries on''' with the next object.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #36c; background:#eaf3ff; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Automatic retry''' — a row in &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; becomes eligible again on the next run. Once the cause is fixed (a fiscal year created late, for instance), no manual action is needed.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Why duplicates are impossible ===&lt;br /&gt;
&lt;br /&gt;
* '''Unique database key''' on &amp;lt;code&amp;gt;(stripe_object_id, entity)&amp;lt;/code&amp;gt; — protects even against two concurrent cron executions.&lt;br /&gt;
* '''Explicit check before processing''' — avoids even attempting to post an entry for an already-finalised object.&lt;br /&gt;
&lt;br /&gt;
=== Special cases: &amp;lt;code&amp;gt;adjustment&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;payment_failure_refund&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
These are balance corrections Stripe makes on its own (reversal after a dispute is resolved, automatic refund of a payment that ultimately failed). The module '''records''' them — otherwise they would stay invisible — but '''never''' posts them automatically: the sign of the amount and the underlying cause vary too much. They are created directly in &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, with an explicit message, to be handled manually.&lt;br /&gt;
&lt;br /&gt;
== 5. Accounting entries ==&lt;br /&gt;
&lt;br /&gt;
All lines of a single Stripe event share the same &amp;lt;code&amp;gt;doc_type='stripeaccounting'&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fk_doc&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;doc_ref&amp;lt;/code&amp;gt; triplet: Dolibarr automatically groups them under one piece number, so the module needs no numbering scheme of its own.&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! Event !! What the module does !! Resulting entry&lt;br /&gt;
|-&lt;br /&gt;
| Stripe fee ''(VAT mode &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt;)'' || &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; bank movement || 627xxx / 517xxx entry generated later by Dolibarr&lt;br /&gt;
|-&lt;br /&gt;
| Stripe fee ''(&amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt; mode)'' || Plus: VAT pair posted immediately || Debit deductible VAT, credit reverse-charge VAT ''(net impact nil)''&lt;br /&gt;
|-&lt;br /&gt;
| Stripe fee ''(&amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; mode)'' || Full direct entry || Debit fee account excl. VAT + deductible VAT, credit Stripe account incl. VAT&lt;br /&gt;
|-&lt;br /&gt;
| Subscription / service fees ''(Radar, Billing, Connect…)'' || &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; bank movement || Entry generated later by Dolibarr, on the Stripe supplier account&lt;br /&gt;
|-&lt;br /&gt;
| Payout || Internal bank transfer between the two accounts || Entry generated later by Dolibarr&lt;br /&gt;
|-&lt;br /&gt;
| Refund ''(invoice found)'' || Direct entry || Debit customer account 411xxx, credit Stripe account 517xxx&lt;br /&gt;
|-&lt;br /&gt;
| Refund ''(invoice not found)'' || Nothing || Status &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, handle manually&lt;br /&gt;
|-&lt;br /&gt;
| Dispute / chargeback || Direct entry || Debit dispute loss 658xxx, credit Stripe account 517xxx ''(+ fee account if fees apply)''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Why fees and payouts produce no direct entry ===&lt;br /&gt;
&lt;br /&gt;
The historical problem: when a Stripe-paid invoice is transferred to accounting through Dolibarr's standard workflow, the payment is posted at its '''gross''' amount — fees are ignored at that stage.&lt;br /&gt;
&lt;br /&gt;
If the module posted its own entry ''and'' its own bank line on top of that, this line would stay invisible to &amp;lt;code&amp;gt;bankjournal.php&amp;lt;/code&amp;gt; — which only recognises lines attached to &amp;lt;code&amp;gt;doc_type='bank'&amp;lt;/code&amp;gt;. An administrator transferring the bank account to accounting &amp;quot;normally&amp;quot; would then create a '''second''' entry for the very same movement.&lt;br /&gt;
&lt;br /&gt;
'''The chosen solution:''' for fees, subscription fees and payouts, the module now creates only the '''real bank movement''', using Dolibarr's native mechanisms. The native ''&amp;quot;Transfer to accounting&amp;quot;'' button then produces the entry, exactly as for any other bank movement. In those three cases, the module no longer touches &amp;lt;code&amp;gt;llx_accounting_bookkeeping&amp;lt;/code&amp;gt; at all.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:22%;&amp;quot; | Case !! Native mechanism used&lt;br /&gt;
|-&lt;br /&gt;
| Fees and subscription fees || &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; (bank movement with an explicit counterpart account, no third party or invoice), carrying its own &amp;lt;code&amp;gt;accountancy_code&amp;lt;/code&amp;gt;, which &amp;lt;code&amp;gt;bankjournal.php&amp;lt;/code&amp;gt; reads directly.&lt;br /&gt;
|-&lt;br /&gt;
| Payouts || Dolibarr internal transfer: &amp;lt;code&amp;gt;Account::addline()&amp;lt;/code&amp;gt; on both sides, plus &amp;lt;code&amp;gt;add_url_line(…, 'banktransfert')&amp;lt;/code&amp;gt;. The counterpart is posted to &amp;lt;code&amp;gt;ACCOUNTING_ACCOUNT_TRANSFER_CASH&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In both cases the status becomes &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt; — the module's job is done — but '''&amp;lt;code&amp;gt;piece_num&amp;lt;/code&amp;gt; stays empty''': the entry does not exist yet, only &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; is set. After the manual transfer, it can be found with &amp;lt;code&amp;gt;doc_type='bank'&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;fk_doc&amp;lt;/code&amp;gt; equal to the row's &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #fc3; background:#fef6e7; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Worth knowing''' — the payout entry only balances to zero on the transfer account once '''both''' bank accounts (Stripe ''and'' the real bank) have been transferred to accounting, not just one of them.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #d33; background:#fee7e6; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''⚠ &amp;lt;code&amp;gt;STRIPE_AUTO_RECORD_PAYOUT&amp;lt;/code&amp;gt; must stay disabled'''&lt;br /&gt;
&lt;br /&gt;
Once this module handles payouts, untick &amp;quot;Enable automatic recording of Stripe payments&amp;quot; in &amp;lt;code&amp;gt;stripe/admin/stripe.php&amp;lt;/code&amp;gt; — despite its wording, that checkbox only concerns payouts.&lt;br /&gt;
&lt;br /&gt;
Otherwise the official module's webhook and this module would each create their own bank movement for the same payout, unaware of each other.&lt;br /&gt;
&lt;br /&gt;
The core webhook keeps '''no''' trace of the payout id it has processed: should Stripe deliver the event twice (delivery is guaranteed &amp;quot;at least once&amp;quot;), nothing stops it from duplicating on its own either. This module has real idempotency and automatically catches up any missed payout within 35 days.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The &amp;quot;Stripe transfers&amp;quot; page is hidden ===&lt;br /&gt;
&lt;br /&gt;
On activation, &amp;lt;code&amp;gt;modStripeAccounting::init()&amp;lt;/code&amp;gt; disables the &amp;lt;code&amp;gt;stripe/payout.php&amp;lt;/code&amp;gt; menu entry: that page queries the API live without recording anything, and having it alongside this module would only create confusion about which one is authoritative for payouts. &amp;lt;code&amp;gt;remove()&amp;lt;/code&amp;gt; restores the original condition. '''This is the only core table the module modifies''' — deliberate, and documented here for that reason.&lt;br /&gt;
&lt;br /&gt;
=== Per-transaction fees or subscription fees? ===&lt;br /&gt;
&lt;br /&gt;
Stripe bills two distinct things under the generic word &amp;quot;fees&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! !! Per-transaction fees !! Subscription / service fees&lt;br /&gt;
|-&lt;br /&gt;
! Example&lt;br /&gt;
| Commission on each payment || Radar, Billing, Connect&lt;br /&gt;
|-&lt;br /&gt;
! Where to find it&lt;br /&gt;
| The &amp;lt;code&amp;gt;.fee&amp;lt;/code&amp;gt; field of a &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; balance transaction || A dedicated balance transaction, type &amp;lt;code&amp;gt;stripe_fee&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;application_fee&amp;lt;/code&amp;gt; ''(its &amp;lt;code&amp;gt;.fee&amp;lt;/code&amp;gt; is always 0, the amount sits in &amp;lt;code&amp;gt;.amount&amp;lt;/code&amp;gt;)''&lt;br /&gt;
|-&lt;br /&gt;
! Account used&lt;br /&gt;
| The configured fee account (627xxx) || The supplier accounting code of the configured Stripe third party&lt;br /&gt;
|-&lt;br /&gt;
! Type in database&lt;br /&gt;
| &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Limitation of the &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; VAT mode ===&lt;br /&gt;
&lt;br /&gt;
This mode has to split the gross amount into net + VAT, something &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; cannot express. It therefore keeps the previous behaviour: a full direct entry, with no bank movement created. No duplicate risk (precisely because no bank line is produced), but the &amp;lt;code&amp;gt;llx_bank&amp;lt;/code&amp;gt; balance of the Stripe account will never reflect the fees while this mode is active.&lt;br /&gt;
&lt;br /&gt;
== 6. CSV import ==&lt;br /&gt;
&lt;br /&gt;
The import covers the case of a Stripe account '''different''' from the one configured in the official module — another PrestaShop shop with its own merchant account, for example. The API has no access to it: its contents are exported to CSV from the Stripe dashboard, then imported.&lt;br /&gt;
&lt;br /&gt;
=== Starting assumption ===&lt;br /&gt;
&lt;br /&gt;
The invoices and payments of that shop are '''already''' posted in Dolibarr through some other process, and the collection (debit 517, credit 411) is already booked. Only the '''fees''', '''refunds''' and '''payouts''' are missing — which is exactly what the import handles.&lt;br /&gt;
&lt;br /&gt;
=== Interface: a single field ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;import.php&amp;lt;/code&amp;gt; now exposes only one upload field, '''General history''', wired to &amp;lt;code&amp;gt;importGeneralHistory()&amp;lt;/code&amp;gt;. That file alone covers every movement type.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;importPayments()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;importPayouts()&amp;lt;/code&amp;gt; are still implemented and functional, but no longer reachable from the interface; they are documented below for reference.&lt;br /&gt;
&lt;br /&gt;
Like the &amp;quot;Sync now&amp;quot; button, the import is blocked — warning banner, disabled button, server-side guard — while the configuration is incomplete.&lt;br /&gt;
&lt;br /&gt;
=== The three methods ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:24%;&amp;quot; | Method !! Stripe export read !! Processing&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;importGeneralHistory()&amp;lt;/code&amp;gt;&amp;lt;br /&amp;gt;''(the only one exposed)'' || Balance history || Dispatch on the &amp;lt;code&amp;gt;Type&amp;lt;/code&amp;gt; column, see table below&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;importPayments()&amp;lt;/code&amp;gt; || Payments || Fee → fee movement. Amount refunded → &amp;lt;code&amp;gt;refund&amp;lt;/code&amp;gt; row, always in &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;importPayouts()&amp;lt;/code&amp;gt; || Payouts || Exactly the same processing as a payout coming from the API&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
General history dispatch, by &amp;lt;code&amp;gt;Type&amp;lt;/code&amp;gt; column:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:30%;&amp;quot; | Stripe type !! Processing&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt; || Internal bank transfer, as via the API&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;payment&amp;lt;/code&amp;gt; with a fee || Fee movement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_fee&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;application_fee&amp;lt;/code&amp;gt; || Subscription fee, on the Stripe supplier account&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;refund&amp;lt;/code&amp;gt; || Recorded, '''always''' in &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;payout_minimum_balance_hold&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;…_release&amp;lt;/code&amp;gt; || '''Ignored''' — Stripe rolling reserve, no real cash movement, nothing to post&lt;br /&gt;
|-&lt;br /&gt;
| any other type || Recorded as &amp;lt;code&amp;gt;type='other'&amp;lt;/code&amp;gt;, status &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, raw Stripe type kept in the description. No guessed entry.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Columns are matched '''by name''': their order does not matter, and extra unused columns are ignored.&lt;br /&gt;
&lt;br /&gt;
=== Import idempotency ===&lt;br /&gt;
&lt;br /&gt;
The unique key protects against any double import: re-importing the same CSV, or one overlapping a previous import, creates no duplicate.&lt;br /&gt;
&lt;br /&gt;
An important detail: in the general history, &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;payment&amp;lt;/code&amp;gt; rows are indexed by their '''&amp;lt;code&amp;gt;Source&amp;lt;/code&amp;gt;''' column (&amp;lt;code&amp;gt;po_…&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ch_…&amp;lt;/code&amp;gt;), not by the row's own &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;txn_…&amp;lt;/code&amp;gt;) — the very same key the dedicated imports use. Importing the general history '''on top of''' the specific exports therefore never posts the same entry twice, in any order.&lt;br /&gt;
&lt;br /&gt;
Since Stripe identifiers are unique platform-wide, mixing rows from the API account and from several CSV-imported accounts in the same table carries no collision risk.&lt;br /&gt;
&lt;br /&gt;
=== Practical details ===&lt;br /&gt;
&lt;br /&gt;
* '''Source label''' — a free-text field entered at import time (e.g. &amp;quot;DRM shop&amp;quot;) is stored on every created row and serves as a column and filter in the list, to tell several shops apart side by side.&lt;br /&gt;
* '''Amount format''' — Stripe CSVs use the French decimal comma, converted through &amp;lt;code&amp;gt;price2num()&amp;lt;/code&amp;gt;. Dates marked &amp;lt;code&amp;gt;(UTC)&amp;lt;/code&amp;gt; are interpreted as such.&lt;br /&gt;
&lt;br /&gt;
== 7. Configuration ==&lt;br /&gt;
&lt;br /&gt;
The API key and test/live mode are '''not''' re-entered here: they are read, read-only, from the official Stripe module.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:26%;&amp;quot; | Field !! Constant !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| Stripe financial account || &amp;lt;code&amp;gt;STRIPE_BANK_ACCOUNT_FOR_PAYMENTS&amp;lt;/code&amp;gt; ''(official module constant)'' || Bank account selector. No local copy, hence no risk of divergence.&lt;br /&gt;
|-&lt;br /&gt;
| Main bank account || &amp;lt;code&amp;gt;STRIPE_BANK_ACCOUNT_FOR_BANKTRANSFERS&amp;lt;/code&amp;gt; ''(official module constant)'' || Same selector. See the box below.&lt;br /&gt;
|-&lt;br /&gt;
| Fee account || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_FRAIS&amp;lt;/code&amp;gt; || Account number, e.g. 627xxx&lt;br /&gt;
|-&lt;br /&gt;
| Dispute account || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_LITIGES&amp;lt;/code&amp;gt; || Account number, e.g. 658xxx. '''Required''' — used as soon as a dispute occurs, whatever the VAT mode.&lt;br /&gt;
|-&lt;br /&gt;
| Stripe supplier third party || &amp;lt;code&amp;gt;STRIPEACCOUNTING_FOURNISSEUR_STRIPE_ID&amp;lt;/code&amp;gt; || A third party flagged as supplier; its supplier accounting code is what gets used. Optional, unless subscription fees exist.&lt;br /&gt;
|-&lt;br /&gt;
| VAT mode || &amp;lt;code&amp;gt;STRIPEACCOUNTING_VAT_MODE&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Deductible VAT account (intra-EU) || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_TVA_DEDUCTIBLE&amp;lt;/code&amp;gt; || Required when the VAT mode is not &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt;. Stripe always invoices from a non-French EU entity, so the deductible VAT is intra-EU in every case.&lt;br /&gt;
|-&lt;br /&gt;
| VAT due account (intra-EU) || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_TVA_AUTOLIQUIDATION&amp;lt;/code&amp;gt; || Required in &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt; mode only — never used in &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; mode.&lt;br /&gt;
|-&lt;br /&gt;
| VAT rate || &amp;lt;code&amp;gt;STRIPEACCOUNTING_VAT_RATE&amp;lt;/code&amp;gt; || Percentage, 20 by default&lt;br /&gt;
|-&lt;br /&gt;
| Sync frequency || &amp;lt;code&amp;gt;STRIPEACCOUNTING_SYNC_UNITFREQUENCY&amp;lt;/code&amp;gt; || Applied to the scheduled job (in seconds)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #36c; background:#eaf3ff; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Why redefine the main bank account here?'''&lt;br /&gt;
&lt;br /&gt;
The official Stripe module's setup page only renders that field when &amp;lt;code&amp;gt;STRIPE_AUTO_RECORD_PAYOUT&amp;lt;/code&amp;gt; is enabled — and its own save handler resets the value to 0 on every save while the field is not rendered. Yet that setting must stay disabled once this module handles payouts. The field is therefore re-exposed here, writing the core constant directly, so the value stays configurable and stable.&lt;br /&gt;
&lt;br /&gt;
Both account selectors only write their constant when a real account was submitted: saving the page for some unrelated field never overwrites a correct value.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Configuration check ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;StripeAccounting::checkConfig()&amp;lt;/code&amp;gt; returns the list of missing constants. It is called both by the setup page (information banner) and by every sync entry point (the real guard that blocks all processing).&lt;br /&gt;
&lt;br /&gt;
=== Pitfall with accounting account selectors ===&lt;br /&gt;
&lt;br /&gt;
The four fields using &amp;lt;code&amp;gt;FormAccounting::select_account()&amp;lt;/code&amp;gt; (fees, disputes, both VAT accounts) have a &amp;quot;nothing selected&amp;quot; option whose value is '''&amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;''' — a non-empty string, therefore truthy in PHP. A field left blank and saved literally stores &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;StripeAccounting::getAccountConst()&amp;lt;/code&amp;gt; normalises that value to an empty string on read, everywhere these constants are read. No entry can therefore land on the non-existent account &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 8. User interface ==&lt;br /&gt;
&lt;br /&gt;
=== Dashboard ===&lt;br /&gt;
&lt;br /&gt;
Stripe balance (live API call), number of unreconciled transactions, total fees for the month, pending payouts, and a '''Sync now''' button — disabled, with a banner listing the missing constants, while the configuration is incomplete.&lt;br /&gt;
&lt;br /&gt;
=== Transaction list ===&lt;br /&gt;
&lt;br /&gt;
A paginated, sortable, filterable list built with the same mechanism as native Dolibarr lists: the icon at the top right of the table lets each user pick their columns, and the preference is stored per user.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:20%;&amp;quot; | Column !! Content&lt;br /&gt;
|-&lt;br /&gt;
| Amount, Fee, Total || The fee popup shows the VAT on the fee whenever a reverse-charge pair or French VAT was posted&lt;br /&gt;
|-&lt;br /&gt;
| Type, Description || Popup with the Stripe ID, the event or source ID, and the full untruncated description&lt;br /&gt;
|-&lt;br /&gt;
| Third party || The customer resolved through the invoice, or through the source charge for its related fee, or the configured Stripe supplier for a subscription fee&lt;br /&gt;
|-&lt;br /&gt;
| Entry || A &amp;quot;Piece no. X&amp;quot; link to the accounting entry, and/or a link to the related bank movement — see the caveat below&lt;br /&gt;
|-&lt;br /&gt;
| Source, Status || The &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; badge opens a popup with the full error message: no need to query the database to understand a failure&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #fc3; background:#fef6e7; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Reading the &amp;quot;Entry&amp;quot; column''' — on a &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt; row, the link points to the '''bank movement''', not to an accounting piece. The module's &amp;lt;code&amp;gt;piece_num&amp;lt;/code&amp;gt; is never the 627/517 entry for the fee: it is only the reverse-charge VAT pair. The fee entry itself is generated later, by Dolibarr's native button, and is never reported back onto this row.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The page is '''purely informational''': no manual posting is offered there. The module posts automatically, and the actual transfer to accounting for fees and payouts happens through the native &amp;quot;Transfer to accounting&amp;quot; button.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; rows ===&lt;br /&gt;
&lt;br /&gt;
Each payment produces '''two rows''' in the database:&lt;br /&gt;
&lt;br /&gt;
* a &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; row, always in status &amp;lt;code&amp;gt;ignored&amp;lt;/code&amp;gt;, fee 0, never processed — present solely for idempotency;&lt;br /&gt;
* a &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; row for the same payment, linked to the first one.&lt;br /&gt;
&lt;br /&gt;
Both appear separately in the list, but the &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; row also carries the link to the payment and the invoice, resolved through a join.&lt;br /&gt;
&lt;br /&gt;
=== Test mode banner ===&lt;br /&gt;
&lt;br /&gt;
While live mode is off, the dashboard, the setup page and the transaction list all display the same warning as the official Stripe module. It is impossible to forget you are working in test mode.&lt;br /&gt;
&lt;br /&gt;
=== Menus ===&lt;br /&gt;
&lt;br /&gt;
Everything sits under '''Banks and cash → Stripe account''' (the official module's menu), flat, as three entries at the same level:&lt;br /&gt;
&lt;br /&gt;
# Stripe dashboard&lt;br /&gt;
# Stripe transactions&lt;br /&gt;
# CSV import ''(administrators only)''&lt;br /&gt;
&lt;br /&gt;
A dashboard link is also added automatically on the bank account record configured as the Stripe account.&lt;br /&gt;
&lt;br /&gt;
== 9. Scheduled job ==&lt;br /&gt;
&lt;br /&gt;
There are two ways to run the sync, both idempotent and safe to re-run. In both cases the code executed is strictly the same: no behavioural difference between the two triggers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #d33; background:#fee7e6; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''⚠ Neither of them starts on its own.'''&lt;br /&gt;
&lt;br /&gt;
Activating the module creates the &amp;lt;code&amp;gt;StripeAccountingSync&amp;lt;/code&amp;gt; job, but '''disabled by default'''. And even once enabled, the Dolibarr scheduler is triggered by nothing until a system crontab calls it. Without both steps, the sync only happens when &amp;quot;Sync now&amp;quot; is clicked manually.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Step 1 — enable the job ===&lt;br /&gt;
&lt;br /&gt;
Under '''Home → Setup → Modules → Scheduled jobs'''. Since &amp;lt;code&amp;gt;llx_cronjob&amp;lt;/code&amp;gt; is a core table, this setting is made through the interface only, never by direct SQL from the module.&lt;br /&gt;
&lt;br /&gt;
=== Step 2 — a system trigger ===&lt;br /&gt;
&lt;br /&gt;
Pick either option.&lt;br /&gt;
&lt;br /&gt;
'''Option A — Dolibarr scheduler''' ''(recommended when several Dolibarr scheduled jobs coexist)''. Runs every due job, not just this one. Requires step 1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
*/15 * * * * curl &amp;quot;https://your-dolibarr/public/cron/cron_run_jobs_by_url.php?securitykey=YOUR_KEY&amp;amp;userlogin=YOUR_LOGIN&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The security key is generated on the scheduled jobs page, &amp;quot;Security of job execution by URL&amp;quot; button.&lt;br /&gt;
&lt;br /&gt;
'''Option B — the module's CLI script.''' Standalone, refuses to run from a browser, and independent of whether the Dolibarr job is enabled.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
*/15 * * * * php /path/to/htdocs/custom/stripeaccounting/cron/stripe_sync.php &amp;gt;&amp;gt; /var/log/stripeaccounting.log 2&amp;gt;&amp;amp;1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 10. Logging and permissions ==&lt;br /&gt;
&lt;br /&gt;
=== Logging ===&lt;br /&gt;
&lt;br /&gt;
Every API call, generated entry, warning or error is traced in &amp;lt;code&amp;gt;llx_stripeaccounting_log&amp;lt;/code&amp;gt;, readable in the database or through the standard Dolibarr log file. Levels: &amp;lt;code&amp;gt;DEBUG&amp;lt;/code&amp;gt; &amp;lt; &amp;lt;code&amp;gt;INFO&amp;lt;/code&amp;gt; &amp;lt; &amp;lt;code&amp;gt;WARNING&amp;lt;/code&amp;gt; &amp;lt; &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;context&amp;lt;/code&amp;gt; column holds the structured detail as JSON (API payload, computed amounts…).&lt;br /&gt;
&lt;br /&gt;
=== Permissions ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Right !! Controls&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;read&amp;lt;/code&amp;gt; || Access to the dashboard and the transaction list&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;write&amp;lt;/code&amp;gt; || Declared for configuration, but not checked in the code today&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;reconcile&amp;lt;/code&amp;gt; || Manual sync triggering&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In practice, &amp;lt;code&amp;gt;admin/setup.php&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;import.php&amp;lt;/code&amp;gt; only check '''Dolibarr administrator''' status, not the &amp;lt;code&amp;gt;write&amp;lt;/code&amp;gt; right: only administrators can configure the module or import a CSV, whatever is ticked in the module permissions.&lt;br /&gt;
&lt;br /&gt;
== 11. Database schema ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;llx_stripeaccounting_transaction&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
One row per processed Stripe object — charge, fee, refund, dispute or payout — all in the same table, distinguished by the &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt; column.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:24%;&amp;quot; | Column !! style=&amp;quot;width:16%;&amp;quot; | Type !! Role&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rowid&amp;lt;/code&amp;gt; || int AI || Primary key&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;entity&amp;lt;/code&amp;gt; || int || Dolibarr multi-company&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_object_id&amp;lt;/code&amp;gt; || varchar(80) || Stripe identifier — '''idempotency anchor'''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_event_id&amp;lt;/code&amp;gt; || varchar(80) || Event identifier, informational only&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt; || varchar(20) || &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;refund&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;dispute&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;other&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_source_id&amp;lt;/code&amp;gt; || varchar(80) || Source Stripe object (e.g. the charge behind a refund)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;source_label&amp;lt;/code&amp;gt; || varchar(80) || Free-text label entered at CSV import; empty for API rows&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;description&amp;lt;/code&amp;gt; || varchar(255) || Stripe label&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;amount&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;net&amp;lt;/code&amp;gt; || decimal(24,8) || Amounts already converted from Stripe cents&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;currency&amp;lt;/code&amp;gt; || varchar(3) || ISO currency code&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;date_created&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;date_available_on&amp;lt;/code&amp;gt; || datetime || Stripe-side dates&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_facture&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fk_paiement&amp;lt;/code&amp;gt; || int || Resolved Dolibarr invoice and payment, if found&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; || int || Generated &amp;lt;code&amp;gt;llx_bank&amp;lt;/code&amp;gt; line ''(empty for a fee in &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; VAT mode)''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;piece_num&amp;lt;/code&amp;gt; || varchar(20) || Generated accounting piece number, where there is one&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt; || varchar(16) || &amp;lt;code&amp;gt;pending&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ignored&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;error_message&amp;lt;/code&amp;gt; || text || Detail on failure&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;date_creation&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;date_processed&amp;lt;/code&amp;gt; || datetime || Technical timestamps&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_user_creat&amp;lt;/code&amp;gt; || int || User who triggered the processing&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Unique key''' on &amp;lt;code&amp;gt;(stripe_object_id, entity)&amp;lt;/code&amp;gt; — this is what guarantees the same Stripe object can never be inserted twice, even with concurrent executions.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;llx_stripeaccounting_log&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Column !! Role&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;level&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;DEBUG&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;INFO&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;WARNING&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;message&amp;lt;/code&amp;gt; || Short message&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;context&amp;lt;/code&amp;gt; || Structured context as JSON&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_stripeaccounting_transaction&amp;lt;/code&amp;gt; || Related transaction, where applicable&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;datec&amp;lt;/code&amp;gt; || Timestamp&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 12. Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:26%;&amp;quot; | Symptom !! Likely cause !! Action&lt;br /&gt;
|-&lt;br /&gt;
| The &amp;quot;Sync now&amp;quot; button is disabled || Minimum configuration incomplete || Fill in the fields listed in the setup page banner&lt;br /&gt;
|-&lt;br /&gt;
| A transaction stays in &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; || Entry rejected by Dolibarr (non-existent account, closed period), or refund not matched || Read &amp;lt;code&amp;gt;error_message&amp;lt;/code&amp;gt; on the row, then the detail in the log table&lt;br /&gt;
|-&lt;br /&gt;
| The Stripe balance is not displayed || API key missing or invalid in the official Stripe module || Check &amp;lt;code&amp;gt;stripe/admin/stripe.php&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| A refund is never reconciled || The original payment was not found through &amp;lt;code&amp;gt;ext_payment_id&amp;lt;/code&amp;gt; || Check that the Stripe payment was recorded by the official module with that identifier&lt;br /&gt;
|-&lt;br /&gt;
| A &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt; stays in &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; || Stripe supplier third party not set, or has no supplier accounting code || Fill the field in setup, and complete the third party record&lt;br /&gt;
|-&lt;br /&gt;
| A CSV-imported refund stays in &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; || '''Normal and expected''' — that account is not linked to &amp;lt;code&amp;gt;ext_payment_id&amp;lt;/code&amp;gt; || Handle the invoice and refund manually in accounting&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 13. Pitfalls encountered ==&lt;br /&gt;
&lt;br /&gt;
Development notes, kept so nobody falls into them again.&lt;br /&gt;
&lt;br /&gt;
* '''&amp;lt;code&amp;gt;PaymentVarious::create()&amp;lt;/code&amp;gt;''' only updates &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; in the database, never on the PHP object. A &amp;lt;code&amp;gt;fetch()&amp;lt;/code&amp;gt; after &amp;lt;code&amp;gt;create()&amp;lt;/code&amp;gt; is required to get the real value.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;select_comptes()&amp;lt;/code&amp;gt;''' prints its own HTML ''and'' returns the number of accounts. Call it as a bare statement: wrapping it in &amp;lt;code&amp;gt;print&amp;lt;/code&amp;gt; would display that number right after the select tag.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;master.inc.php&amp;lt;/code&amp;gt;, not &amp;lt;code&amp;gt;main.inc.php&amp;lt;/code&amp;gt;''' for the CLI script. The latter expects an HTTP session and, in pure CLI, exits silently — no output, no log, return code 0 — inside its redirect to the login page. This gives the misleading impression that the script &amp;quot;does nothing&amp;quot; rather than a real error.&lt;br /&gt;
* '''Core libraries''' — &amp;lt;code&amp;gt;master.inc.php&amp;lt;/code&amp;gt; does not load everything &amp;lt;code&amp;gt;main.inc.php&amp;lt;/code&amp;gt; loads for the web (e.g. &amp;lt;code&amp;gt;core/lib/date.lib.php&amp;lt;/code&amp;gt;, required by &amp;lt;code&amp;gt;BookKeeping&amp;lt;/code&amp;gt;). Include them explicitly if the CLI script evolves.&lt;br /&gt;
* '''The &amp;quot;nothing selected&amp;quot; option is &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;''' in accounting account selectors — see the Configuration section.&lt;br /&gt;
&lt;br /&gt;
== 14. Known limitations ==&lt;br /&gt;
&lt;br /&gt;
* '''Zero-decimal currencies''' (JPY, KRW…) are not handled: amounts are divided by 100 assuming two decimals. Intended use: EUR.&lt;br /&gt;
* '''The 35-day window''' is not configurable. A sync interrupted for longer must be caught up manually.&lt;br /&gt;
* '''Refund matching''' — relies on &amp;lt;code&amp;gt;ext_payment_id&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ext_payment_site&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;llx_paiement&amp;lt;/code&amp;gt;, filled in by the standard Stripe payment flow. A payment recorded any other way cannot be matched automatically. Matching goes through the '''PaymentIntent id''', never the charge id: the core Stripe module never stores the latter ''(it stores either the raw PaymentIntent, or a composite value, depending on the payment path taken)''.&lt;br /&gt;
* '''CSV import assumes French notation''': an export with a decimal point would not be parsed correctly.&lt;br /&gt;
* '''The &amp;quot;Transfer&amp;quot; column of the Payments CSV''' is stored for information only: it is not used to check that the sum of payments matches the imported payout amount.&lt;br /&gt;
* '''CSV-imported refunds always land in &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;''' — intended behaviour, not a bug.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; VAT mode''' — the Stripe account's bank balance does not reflect the fees, see section 5.&lt;br /&gt;
&lt;br /&gt;
[[Category:Dolibarr]]&lt;br /&gt;
[[Category:Modules]]&lt;br /&gt;
[[Category:Accounting]]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Stripeaccounting&amp;diff=549</id>
		<title>Stripeaccounting</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Stripeaccounting&amp;diff=549"/>
				<updated>2026-08-02T12:36:13Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:StripeAccounting — Documentation technique}}&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Us.png|link=Stripeaccounting/en]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border:1px solid #c8ccd1; background:#f8f9fa; border-radius:4px; padding:1em 1.2em; margin:0 0 1.5em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''StripeAccounting''' est un module Dolibarr de '''rapprochement comptable Stripe'''.&lt;br /&gt;
&lt;br /&gt;
Il lit l'API Stripe (ou un export CSV), repère les mouvements que le module Stripe officiel ne comptabilise pas — frais, remboursements, litiges, virements — et pose les écritures manquantes.&lt;br /&gt;
&lt;br /&gt;
: '''Compatibilité''' — Dolibarr 17+, PHP 7.2 → 8.5&lt;br /&gt;
: '''Dépend de''' — modules Stripe, Banque, Comptabilité en partie double&lt;br /&gt;
: '''Voir aussi''' — [[README-fr|Installation et guide utilisateur]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== 1. Principes de fonctionnement ==&lt;br /&gt;
&lt;br /&gt;
Quatre règles gouvernent tout le module.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:22%;&amp;quot; | Principe !! Ce que ça veut dire&lt;br /&gt;
|-&lt;br /&gt;
| '''Complémentaire''' || Le module ne crée aucun paiement, aucune facture, aucun webhook. Il lit Stripe et complète la comptabilité, rien de plus.&lt;br /&gt;
|-&lt;br /&gt;
| '''Idempotent''' || Chaque objet Stripe n'est traité qu'une fois, quel que soit le nombre de relances de la synchronisation.&lt;br /&gt;
|-&lt;br /&gt;
| '''Jamais de devinette''' || Si une opération ne peut pas être rattachée avec certitude, rien n'est posté : la ligne passe en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; pour revue manuelle.&lt;br /&gt;
|-&lt;br /&gt;
| '''Configuration bloquante''' || Tant que la configuration minimale est incomplète, aucune synchronisation ne démarre (ni bouton, ni cron, ni import).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2. Prérequis ==&lt;br /&gt;
&lt;br /&gt;
=== Modules Dolibarr requis ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Module !! Ce qu'il apporte&lt;br /&gt;
|-&lt;br /&gt;
| '''Stripe''' (&amp;lt;code&amp;gt;modStripe&amp;lt;/code&amp;gt;) || Clé API, mode test/live, compte financier Stripe&lt;br /&gt;
|-&lt;br /&gt;
| '''Banque''' (&amp;lt;code&amp;gt;modBanque&amp;lt;/code&amp;gt;) || Tables &amp;lt;code&amp;gt;llx_bank&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;llx_bank_account&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| '''Comptabilité en partie double''' (&amp;lt;code&amp;gt;modAccounting&amp;lt;/code&amp;gt;) || Table &amp;lt;code&amp;gt;llx_accounting_bookkeeping&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Réglage Dolibarr indispensable ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ACCOUNTING_ACCOUNT_TRANSFER_CASH&amp;lt;/code&amp;gt; doit être renseigné dans '''Comptabilité → Configuration → Comptes par défaut'''. Sans lui, le virement interne généré par les payouts ne peut pas être transféré en comptabilité (limite de Dolibarr, pas du module).&lt;br /&gt;
&lt;br /&gt;
l’option s'appelle : '''Compte comptable par défaut pour les virements internes'''&lt;br /&gt;
&lt;br /&gt;
=== Notes ===&lt;br /&gt;
&lt;br /&gt;
* Le SDK PHP Stripe n'est pas dupliqué : le module réutilise la copie du cœur (&amp;lt;code&amp;gt;includes/stripe/stripe-php/&amp;lt;/code&amp;gt;).&lt;br /&gt;
* Le code évite volontairement toute syntaxe PHP postérieure à 7.2 (pas de &amp;lt;code&amp;gt;match&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;?-&amp;gt;&amp;lt;/code&amp;gt;, enums, propriétés typées, &amp;lt;code&amp;gt;str_contains&amp;lt;/code&amp;gt;…) pour couvrir toute la plage 7.2 → 8.5.&lt;br /&gt;
&lt;br /&gt;
== 3. Arborescence ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
custom/stripeaccounting/&lt;br /&gt;
├── core/modules/modStripeAccounting.class.php   Descripteur (droits, menus, cron, constantes)&lt;br /&gt;
├── class/&lt;br /&gt;
│   ├── StripeApi.class.php                      Wrapper SDK Stripe (lecture seule)&lt;br /&gt;
│   ├── StripeRepository.class.php               Accès SQL + idempotence&lt;br /&gt;
│   ├── StripeLogger.class.php                   Journalisation&lt;br /&gt;
│   ├── StripeAccounting.class.php               Génération des écritures&lt;br /&gt;
│   ├── StripePayout.class.php                   Rapprochement des virements&lt;br /&gt;
│   ├── StripeSync.class.php                     Orchestrateur (point d'entrée du cron)&lt;br /&gt;
│   ├── StripeCsvImporter.class.php              Import CSV&lt;br /&gt;
│   └── actions_stripeaccounting.class.php       Hook 'bankcard'&lt;br /&gt;
├── admin/setup.php                              Configuration&lt;br /&gt;
├── import.php                                   Import CSV&lt;br /&gt;
├── dashboard.php                                Tableau de bord&lt;br /&gt;
├── transaction_list.php                         Liste des transactions&lt;br /&gt;
├── cron/stripe_sync.php                         Point d'entrée CLI&lt;br /&gt;
├── lib/stripeaccounting.lib.php&lt;br /&gt;
├── sql/&lt;br /&gt;
├── langs/{fr_FR,en_US,es_ES,it_IT,de_DE}/&lt;br /&gt;
└── css/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sens des dépendances ===&lt;br /&gt;
&lt;br /&gt;
: pages et hook → &amp;lt;code&amp;gt;StripeSync&amp;lt;/code&amp;gt; → (&amp;lt;code&amp;gt;StripeApi&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StripeRepository&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StripeAccounting&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StripePayout&amp;lt;/code&amp;gt;) → &amp;lt;code&amp;gt;StripeLogger&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:26%;&amp;quot; | Classe !! Rôle&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeApi&amp;lt;/code&amp;gt; || Interroge le SDK Stripe (balance transactions, charges, remboursements, litiges, payouts) avec pagination automatique. Aucun accès base, aucune écriture.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeRepository&amp;lt;/code&amp;gt; || Tout le SQL des deux tables du module. &amp;lt;code&amp;gt;upsertTransaction()&amp;lt;/code&amp;gt; est le point d'idempotence.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeLogger&amp;lt;/code&amp;gt; || Écrit dans &amp;lt;code&amp;gt;llx_stripeaccounting_log&amp;lt;/code&amp;gt; et en miroir dans &amp;lt;code&amp;gt;dol_syslog()&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeAccounting&amp;lt;/code&amp;gt; || Construit les écritures (remboursement, litige, TVA autoliquidation) ou les mouvements bancaires (frais). Expose &amp;lt;code&amp;gt;checkConfig()&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripePayout&amp;lt;/code&amp;gt; || Crée le virement bancaire interne entre le compte Stripe et la banque réelle.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeSync&amp;lt;/code&amp;gt; || Orchestrateur : une méthode par flux, plus &amp;lt;code&amp;gt;reconcileStripeAccount()&amp;lt;/code&amp;gt; qui enchaîne tout.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeCsvImporter&amp;lt;/code&amp;gt; || Alimente le même pipeline depuis un export CSV Stripe.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ActionsStripeAccounting&amp;lt;/code&amp;gt; || Hook &amp;lt;code&amp;gt;bankcard&amp;lt;/code&amp;gt; : lien vers le tableau de bord sur la fiche du compte Stripe.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 4. Synchronisation et idempotence ==&lt;br /&gt;
&lt;br /&gt;
Chaque flux (&amp;lt;code&amp;gt;syncFees&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncRefunds&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncDisputes&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncPayouts&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncTransactions&amp;lt;/code&amp;gt;) suit toujours les mêmes étapes :&lt;br /&gt;
&lt;br /&gt;
# '''Vérifier la configuration''' — si elle est incomplète : log &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt;, arrêt immédiat, aucun appel API.&lt;br /&gt;
# '''Lister les objets Stripe''' sur une fenêtre glissante de '''35 jours'''.&lt;br /&gt;
# '''Filtrer''' — un objet est ignoré seulement s'il existe déjà ''et'' que son statut est &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;ignored&amp;lt;/code&amp;gt;. Une ligne en &amp;lt;code&amp;gt;pending&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; est '''retentée''' à ce run.&lt;br /&gt;
# '''Enregistrer''' en statut &amp;lt;code&amp;gt;pending&amp;lt;/code&amp;gt;, puis générer l'écriture ou le mouvement bancaire.&lt;br /&gt;
# '''Conclure''' — succès : statut &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt;. Échec : statut &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; avec le message, et '''le lot continue''' sur l'objet suivant.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #36c; background:#eaf3ff; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Reprise automatique''' — une ligne en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; redevient éligible au run suivant. Une fois la cause corrigée (par exemple un exercice comptable créé tardivement), aucune intervention manuelle n'est nécessaire.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi les doublons sont impossibles ===&lt;br /&gt;
&lt;br /&gt;
* '''Clé unique en base''' sur &amp;lt;code&amp;gt;(stripe_object_id, entity)&amp;lt;/code&amp;gt; — protège même contre deux exécutions concurrentes du cron.&lt;br /&gt;
* '''Test explicite avant traitement''' — évite jusqu'à la tentative d'écriture pour un objet déjà finalisé.&lt;br /&gt;
&lt;br /&gt;
=== Cas particuliers : &amp;lt;code&amp;gt;adjustment&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;payment_failure_refund&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Ce sont des corrections de solde effectuées par Stripe lui-même (réversion après litige, remboursement d'un paiement finalement échoué). Le module les '''enregistre''' — sinon elles resteraient invisibles — mais ne les comptabilise '''jamais''' automatiquement : le signe du montant et la cause varient trop. Elles sont créées directement en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, avec un message explicite, à traiter manuellement.&lt;br /&gt;
&lt;br /&gt;
== 5. Écritures comptables ==&lt;br /&gt;
&lt;br /&gt;
Toutes les lignes d'un même évènement partagent le triplet &amp;lt;code&amp;gt;doc_type='stripeaccounting'&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fk_doc&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;doc_ref&amp;lt;/code&amp;gt; : Dolibarr les regroupe automatiquement sous un même numéro de pièce, sans numérotation propre au module.&lt;br /&gt;
&lt;br /&gt;
=== Vue d'ensemble ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! Évènement !! Ce que fait le module !! Résultat comptable&lt;br /&gt;
|-&lt;br /&gt;
| Frais Stripe ''(TVA &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt;)'' || Mouvement bancaire &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; || Écriture 627xxx / 517xxx générée plus tard par Dolibarr&lt;br /&gt;
|-&lt;br /&gt;
| Frais Stripe ''(mode &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt;)'' || En plus : paire TVA postée immédiatement || Débit TVA déductible, crédit TVA autoliquidation ''(impact net nul)''&lt;br /&gt;
|-&lt;br /&gt;
| Frais Stripe ''(mode &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt;)'' || Écriture directe complète || Débit compte de frais HT + TVA déductible, crédit compte Stripe TTC&lt;br /&gt;
|-&lt;br /&gt;
| Frais d'abonnement / service ''(Radar, Billing, Connect…)'' || Mouvement bancaire &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; || Écriture générée plus tard par Dolibarr, sur le compte fournisseur Stripe&lt;br /&gt;
|-&lt;br /&gt;
| Virement (payout) || Virement bancaire interne entre les 2 comptes || Écriture générée plus tard par Dolibarr&lt;br /&gt;
|-&lt;br /&gt;
| Remboursement ''(facture retrouvée)'' || Écriture directe || Débit compte client 411xxx, crédit compte Stripe 517xxx&lt;br /&gt;
|-&lt;br /&gt;
| Remboursement ''(facture introuvable)'' || Rien || Statut &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, à traiter manuellement&lt;br /&gt;
|-&lt;br /&gt;
| Litige / chargeback || Écriture directe || Débit perte sur litiges 658xxx, crédit compte Stripe 517xxx ''(+ compte de frais si frais associés)''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi frais et virements ne génèrent pas d'écriture directe ===&lt;br /&gt;
&lt;br /&gt;
Le problème historique : quand une facture Stripe est transférée en comptabilité par le workflow standard de Dolibarr, le paiement est comptabilisé pour son montant '''brut''' — les frais sont ignorés à cette étape.&lt;br /&gt;
&lt;br /&gt;
Si le module postait ''en plus'' sa propre écriture ''et'' sa propre ligne bancaire, cette ligne resterait invisible pour &amp;lt;code&amp;gt;bankjournal.php&amp;lt;/code&amp;gt; — qui ne reconnaît que les lignes rattachées à &amp;lt;code&amp;gt;doc_type='bank'&amp;lt;/code&amp;gt;. Un administrateur transférant « normalement » le compte bancaire en comptabilité créait alors une '''seconde''' écriture pour le même mouvement.&lt;br /&gt;
&lt;br /&gt;
'''La solution retenue :''' pour les frais, les frais d'abonnement et les virements, le module ne crée plus que le '''mouvement bancaire réel''', avec les mécanismes natifs de Dolibarr. C'est ensuite le bouton natif ''« Transférer en comptabilité »'' qui produit l'écriture, comme pour n'importe quel autre mouvement bancaire. Le module ne touche donc plus du tout &amp;lt;code&amp;gt;llx_accounting_bookkeeping&amp;lt;/code&amp;gt; dans ces trois cas.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:22%;&amp;quot; | Cas !! Mécanisme natif utilisé&lt;br /&gt;
|-&lt;br /&gt;
| Frais et frais d'abonnement || &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; (mouvement bancaire avec compte de contrepartie, sans tiers ni facture), avec son propre &amp;lt;code&amp;gt;accountancy_code&amp;lt;/code&amp;gt; que &amp;lt;code&amp;gt;bankjournal.php&amp;lt;/code&amp;gt; lit directement.&lt;br /&gt;
|-&lt;br /&gt;
| Virements (payouts) || Virement interne Dolibarr : &amp;lt;code&amp;gt;Account::addline()&amp;lt;/code&amp;gt; des deux côtés, plus &amp;lt;code&amp;gt;add_url_line(…, 'banktransfert')&amp;lt;/code&amp;gt;. La contrepartie est imputée sur &amp;lt;code&amp;gt;ACCOUNTING_ACCOUNT_TRANSFER_CASH&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Dans les deux cas, le statut passe à &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt; — le module a fini son travail — mais '''&amp;lt;code&amp;gt;piece_num&amp;lt;/code&amp;gt; reste vide''' : l'écriture n'existe pas encore, seul &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; est renseigné. Après transfert manuel, on la retrouve avec &amp;lt;code&amp;gt;doc_type='bank'&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;fk_doc&amp;lt;/code&amp;gt; égal au &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; de la ligne.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #fc3; background:#fef6e7; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''À savoir''' — l'écriture des virements ne s'équilibre à zéro sur le compte de transfert que lorsque '''les deux''' comptes bancaires (Stripe ''et'' la banque réelle) ont été transférés en comptabilité, pas seulement un des deux.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #d33; background:#fee7e6; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''⚠ &amp;lt;code&amp;gt;STRIPE_AUTO_RECORD_PAYOUT&amp;lt;/code&amp;gt; doit rester désactivé'''&lt;br /&gt;
&lt;br /&gt;
Dès lors que ce module gère les virements, décochez « Activer l'enregistrement automatique des paiements Stripe » dans &amp;lt;code&amp;gt;stripe/admin/stripe.php&amp;lt;/code&amp;gt; — malgré son libellé, cette case ne concerne que les virements.&lt;br /&gt;
&lt;br /&gt;
Sinon, le webhook du module officiel et ce module créeraient chacun leur propre mouvement bancaire pour le même virement, sans le savoir l'un de l'autre.&lt;br /&gt;
&lt;br /&gt;
Le webhook cœur ne conserve d'ailleurs '''aucune''' trace de l'id du virement traité : en cas de double livraison Stripe (garantie « au moins une fois »), rien ne l'empêche de doublonner tout seul. Ce module, lui, a une vraie idempotence et rattrape automatiquement tout virement manqué sur 35 jours.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Page « Transferts Stripe » masquée ===&lt;br /&gt;
&lt;br /&gt;
À l'activation, &amp;lt;code&amp;gt;modStripeAccounting::init()&amp;lt;/code&amp;gt; désactive l'entrée de menu &amp;lt;code&amp;gt;stripe/payout.php&amp;lt;/code&amp;gt; : cette page interroge l'API en direct sans rien enregistrer, et sa coexistence avec ce module ne créerait qu'une confusion sur ce qui fait foi pour les virements. &amp;lt;code&amp;gt;remove()&amp;lt;/code&amp;gt; restaure la condition d'origine. '''C'est la seule table du cœur que ce module modifie''' — délibéré, et documenté ici pour cette raison.&lt;br /&gt;
&lt;br /&gt;
=== Frais par transaction ou frais d'abonnement ? ===&lt;br /&gt;
&lt;br /&gt;
Stripe facture deux choses distinctes sous le mot « frais » :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! !! Frais par transaction !! Frais d'abonnement / service&lt;br /&gt;
|-&lt;br /&gt;
! Exemple&lt;br /&gt;
| Commission sur chaque encaissement || Radar, Billing, Connect&lt;br /&gt;
|-&lt;br /&gt;
! Où le trouver&lt;br /&gt;
| Champ &amp;lt;code&amp;gt;.fee&amp;lt;/code&amp;gt; d'une balance transaction de type &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; || Balance transaction dédiée, de type &amp;lt;code&amp;gt;stripe_fee&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;application_fee&amp;lt;/code&amp;gt; ''(le &amp;lt;code&amp;gt;.fee&amp;lt;/code&amp;gt; y vaut toujours 0, le montant est dans &amp;lt;code&amp;gt;.amount&amp;lt;/code&amp;gt;)''&lt;br /&gt;
|-&lt;br /&gt;
! Compte utilisé&lt;br /&gt;
| Compte de frais configuré (627xxx) || Code comptable fournisseur du tiers Stripe configuré&lt;br /&gt;
|-&lt;br /&gt;
! Type en base&lt;br /&gt;
| &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Limite du mode TVA &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Ce mode doit scinder le montant TTC en HT + TVA, un découpage que &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; ne sait pas exprimer. Il reste donc sur l'ancien comportement : écriture directe complète, aucun mouvement bancaire créé. Pas de risque de doublon (puisque aucune ligne bancaire n'est produite), mais le solde &amp;lt;code&amp;gt;llx_bank&amp;lt;/code&amp;gt; du compte Stripe ne reflétera jamais les frais tant que ce mode est actif.&lt;br /&gt;
&lt;br /&gt;
== 6. Import CSV ==&lt;br /&gt;
&lt;br /&gt;
L'import couvre le cas d'un compte Stripe '''différent''' de celui configuré dans le module officiel — par exemple une autre boutique PrestaShop avec son propre compte marchand. L'API n'y a pas accès : le contenu est exporté en CSV depuis le dashboard Stripe, puis importé.&lt;br /&gt;
&lt;br /&gt;
=== Hypothèse de départ ===&lt;br /&gt;
&lt;br /&gt;
Les factures et paiements de cette boutique sont '''déjà''' comptabilisés dans Dolibarr par un autre processus, et l'encaissement (débit 517, crédit 411) est déjà posé. Seuls manquent les '''frais''', les '''remboursements''' et les '''virements''' — c'est exactement ce que l'import traite.&lt;br /&gt;
&lt;br /&gt;
=== Interface : un seul champ ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;import.php&amp;lt;/code&amp;gt; n'expose plus qu'un champ d'upload, '''Historique général''', câblé sur &amp;lt;code&amp;gt;importGeneralHistory()&amp;lt;/code&amp;gt;. Ce fichier couvre à lui seul tous les types de mouvements.&lt;br /&gt;
&lt;br /&gt;
Les méthodes &amp;lt;code&amp;gt;importPayments()&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;importPayouts()&amp;lt;/code&amp;gt; restent implémentées et fonctionnelles, mais ne sont plus atteignables depuis l'interface ; elles sont documentées ci-dessous pour mémoire.&lt;br /&gt;
&lt;br /&gt;
Comme le bouton « Synchroniser maintenant », l'import est bloqué — bandeau d'alerte, bouton désactivé, garde-fou côté serveur — tant que la configuration est incomplète.&lt;br /&gt;
&lt;br /&gt;
=== Les trois méthodes ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:24%;&amp;quot; | Méthode !! Export Stripe lu !! Traitement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;importGeneralHistory()&amp;lt;/code&amp;gt;&amp;lt;br /&amp;gt;''(seule exposée)'' || Balance history || Aiguillage par colonne &amp;lt;code&amp;gt;Type&amp;lt;/code&amp;gt;, voir tableau ci-dessous&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;importPayments()&amp;lt;/code&amp;gt; || Payments || Frais → écriture de frais. Montant remboursé → ligne &amp;lt;code&amp;gt;refund&amp;lt;/code&amp;gt; toujours en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;importPayouts()&amp;lt;/code&amp;gt; || Payouts || Exactement le même traitement qu'un payout venu de l'API&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Aiguillage de l'historique général, par colonne &amp;lt;code&amp;gt;Type&amp;lt;/code&amp;gt; :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:30%;&amp;quot; | Type Stripe !! Traitement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt; || Virement bancaire interne, comme via l'API&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;payment&amp;lt;/code&amp;gt; avec frais || Mouvement de frais&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_fee&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;application_fee&amp;lt;/code&amp;gt; || Frais d'abonnement, sur le compte fournisseur Stripe&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;refund&amp;lt;/code&amp;gt; || Enregistré, '''toujours''' en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;payout_minimum_balance_hold&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;…_release&amp;lt;/code&amp;gt; || '''Ignorés''' — réserve glissante Stripe, impact net nul, rien à comptabiliser&lt;br /&gt;
|-&lt;br /&gt;
| tout autre type || Enregistré en &amp;lt;code&amp;gt;type='other'&amp;lt;/code&amp;gt;, statut &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, type brut conservé dans la description. Aucune écriture devinée.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les colonnes sont reconnues '''par leur nom''' : l'ordre importe peu, et les colonnes en plus non utilisées sont ignorées.&lt;br /&gt;
&lt;br /&gt;
=== Idempotence de l'import ===&lt;br /&gt;
&lt;br /&gt;
La clé unique protège contre tout double import : réimporter le même CSV, ou un CSV qui chevauche un import précédent, ne crée aucun doublon.&lt;br /&gt;
&lt;br /&gt;
Point important : dans l'historique général, les lignes &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;payment&amp;lt;/code&amp;gt; sont indexées par leur colonne '''&amp;lt;code&amp;gt;Source&amp;lt;/code&amp;gt;''' (&amp;lt;code&amp;gt;po_…&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ch_…&amp;lt;/code&amp;gt;), pas par l'&amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt; de la ligne (&amp;lt;code&amp;gt;txn_…&amp;lt;/code&amp;gt;) — soit exactement la même clé que les imports dédiés. Importer l'historique général '''en plus''' des exports spécifiques ne poste donc jamais deux fois la même écriture, quel que soit l'ordre.&lt;br /&gt;
&lt;br /&gt;
Les identifiants Stripe étant uniques à l'échelle de la plateforme, mélanger dans la même table des lignes venant du compte API et de plusieurs comptes importés en CSV ne présente aucun risque de collision.&lt;br /&gt;
&lt;br /&gt;
=== Détails pratiques ===&lt;br /&gt;
&lt;br /&gt;
* '''Libellé source''' — un champ libre saisi à l'import (ex. « Boutique DRM ») est stocké sur chaque ligne créée et sert de colonne et de filtre dans la liste, pour distinguer plusieurs boutiques côte à côte.&lt;br /&gt;
* '''Format des montants''' — les CSV Stripe utilisent la virgule décimale française, convertie via &amp;lt;code&amp;gt;price2num()&amp;lt;/code&amp;gt;. Les dates marquées &amp;lt;code&amp;gt;(UTC)&amp;lt;/code&amp;gt; sont interprétées comme telles.&lt;br /&gt;
&lt;br /&gt;
== 7. Configuration ==&lt;br /&gt;
&lt;br /&gt;
La clé API et le mode test/live ne sont '''pas''' ressaisis ici : ils sont lus en lecture seule depuis le module Stripe officiel.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:26%;&amp;quot; | Champ !! Constante !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| Compte financier Stripe || &amp;lt;code&amp;gt;STRIPE_BANK_ACCOUNT_FOR_PAYMENTS&amp;lt;/code&amp;gt; ''(constante du module officiel)'' || Sélecteur de compte bancaire. Aucune copie locale, donc aucun risque de divergence.&lt;br /&gt;
|-&lt;br /&gt;
| Compte bancaire principal || &amp;lt;code&amp;gt;STRIPE_BANK_ACCOUNT_FOR_BANKTRANSFERS&amp;lt;/code&amp;gt; ''(constante du module officiel)'' || Même sélecteur. Voir l'encadré ci-dessous.&lt;br /&gt;
|-&lt;br /&gt;
| Compte de frais || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_FRAIS&amp;lt;/code&amp;gt; || Numéro de compte, ex. 627xxx&lt;br /&gt;
|-&lt;br /&gt;
| Compte de litiges || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_LITIGES&amp;lt;/code&amp;gt; || Numéro de compte, ex. 658xxx. '''Requis''' — utilisé dès qu'un litige survient, quel que soit le mode TVA.&lt;br /&gt;
|-&lt;br /&gt;
| Tiers fournisseur Stripe || &amp;lt;code&amp;gt;STRIPEACCOUNTING_FOURNISSEUR_STRIPE_ID&amp;lt;/code&amp;gt; || Tiers marqué fournisseur ; c'est son code comptable fournisseur qui est utilisé. Optionnel, sauf s'il existe des frais d'abonnement.&lt;br /&gt;
|-&lt;br /&gt;
| Mode TVA || &amp;lt;code&amp;gt;STRIPEACCOUNTING_VAT_MODE&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Compte TVA déductible (intracommunautaire) || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_TVA_DEDUCTIBLE&amp;lt;/code&amp;gt; || Requis si mode TVA ≠ &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt;. Stripe facturant toujours depuis une entité UE non française, la TVA déductible est intracommunautaire dans tous les cas.&lt;br /&gt;
|-&lt;br /&gt;
| Compte de TVA due (intracommunautaire) || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_TVA_AUTOLIQUIDATION&amp;lt;/code&amp;gt; || Requis en mode &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt; uniquement — jamais utilisé en mode &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| Taux de TVA || &amp;lt;code&amp;gt;STRIPEACCOUNTING_VAT_RATE&amp;lt;/code&amp;gt; || Pourcentage, 20 par défaut&lt;br /&gt;
|-&lt;br /&gt;
| Fréquence de synchronisation || &amp;lt;code&amp;gt;STRIPEACCOUNTING_SYNC_UNITFREQUENCY&amp;lt;/code&amp;gt; || Répercutée sur la tâche planifiée (en secondes)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #36c; background:#eaf3ff; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Pourquoi redéfinir le compte bancaire principal ici ?'''&lt;br /&gt;
&lt;br /&gt;
La page de configuration du module Stripe officiel n'affiche ce champ que si &amp;lt;code&amp;gt;STRIPE_AUTO_RECORD_PAYOUT&amp;lt;/code&amp;gt; est activé — et son handler de sauvegarde remet la valeur à 0 à chaque enregistrement tant que le champ n'est pas rendu. Or ce réglage doit justement rester désactivé quand ce module gère les virements. Le champ est donc réexposé ici, en écrivant directement la constante du cœur, pour que la valeur reste configurable et stable.&lt;br /&gt;
&lt;br /&gt;
Les deux sélecteurs de compte n'écrivent leur constante que si un compte réel a été soumis : enregistrer la page pour un tout autre champ n'écrase jamais une valeur correcte.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Vérification de la configuration ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;StripeAccounting::checkConfig()&amp;lt;/code&amp;gt; renvoie la liste des constantes manquantes. Elle est appelée à la fois par la page de configuration (bandeau d'information) et par chaque point d'entrée de synchronisation (garde-fou réel qui bloque tout traitement).&lt;br /&gt;
&lt;br /&gt;
=== Piège des sélecteurs de compte comptable ===&lt;br /&gt;
&lt;br /&gt;
Les quatre champs utilisant &amp;lt;code&amp;gt;FormAccounting::select_account()&amp;lt;/code&amp;gt; (frais, litiges, les deux comptes TVA) ont une option « rien sélectionné » dont la valeur est '''&amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;''' — une chaîne non vide, donc vraie en PHP. Un champ laissé vide et enregistré stocke littéralement &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;StripeAccounting::getAccountConst()&amp;lt;/code&amp;gt; normalise cette valeur en chaîne vide à la lecture, partout où ces constantes sont lues. Aucune écriture ne peut donc atterrir sur le compte inexistant &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 8. Interface ==&lt;br /&gt;
&lt;br /&gt;
=== Tableau de bord ===&lt;br /&gt;
&lt;br /&gt;
Solde Stripe (appel API en direct), nombre de transactions non rapprochées, total des frais du mois, payouts en attente, et bouton '''Synchroniser maintenant''' — désactivé, avec bandeau listant les constantes manquantes, tant que la configuration est incomplète.&lt;br /&gt;
&lt;br /&gt;
=== Liste des transactions ===&lt;br /&gt;
&lt;br /&gt;
Liste paginée, triable et filtrable, construite avec le même mécanisme que les listes natives Dolibarr : l'icône en haut à droite du tableau permet à chaque utilisateur de choisir ses colonnes, et la préférence est mémorisée par utilisateur.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:20%;&amp;quot; | Colonne !! Contenu&lt;br /&gt;
|-&lt;br /&gt;
| Montant, Frais, Total || Le popup sur les frais indique la TVA sur frais quand une paire d'autoliquidation ou une TVA française a été postée&lt;br /&gt;
|-&lt;br /&gt;
| Type, Description || Popup avec l'ID Stripe, l'ID d'évènement ou de source, et la description complète non tronquée&lt;br /&gt;
|-&lt;br /&gt;
| Tiers || Le client résolu via la facture, ou via la charge source pour son frais associé, ou le tiers fournisseur Stripe pour un frais d'abonnement&lt;br /&gt;
|-&lt;br /&gt;
| Écriture || Lien « Pièce n°X » vers l'écriture, et/ou lien vers le mouvement bancaire associé — voir la nuance ci-dessous&lt;br /&gt;
|-&lt;br /&gt;
| Source, Statut || Le badge &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; ouvre un popup avec le message d'erreur complet : plus besoin d'aller en base pour comprendre un échec&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #fc3; background:#fef6e7; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Lire la colonne « Écriture »''' — sur une ligne &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt;, le lien pointe vers le '''mouvement bancaire''', pas vers une pièce comptable. Le &amp;lt;code&amp;gt;piece_num&amp;lt;/code&amp;gt; du module, lui, n'est jamais l'écriture 627/517 du frais : c'est uniquement la paire TVA d'autoliquidation. L'écriture du frais est générée plus tard, par le bouton natif de Dolibarr, et n'est jamais reportée sur cette ligne.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La page est '''purement consultative''' : aucune comptabilisation manuelle n'y est proposée. Le module comptabilise automatiquement, et le transfert en comptabilité des frais et virements se fait depuis le bouton natif « Transférer en comptabilité ».&lt;br /&gt;
&lt;br /&gt;
=== Lignes &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Chaque paiement produit '''deux lignes''' en base :&lt;br /&gt;
&lt;br /&gt;
* une ligne &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt;, toujours en statut &amp;lt;code&amp;gt;ignored&amp;lt;/code&amp;gt;, frais à 0, jamais traitée — présente uniquement pour l'idempotence ;&lt;br /&gt;
* une ligne &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; pour le même paiement, liée à la première.&lt;br /&gt;
&lt;br /&gt;
Les deux apparaissent séparément dans la liste, mais la ligne &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; porte elle aussi le lien vers le paiement et la facture, résolu par jointure.&lt;br /&gt;
&lt;br /&gt;
=== Bandeau mode test ===&lt;br /&gt;
&lt;br /&gt;
Tant que le mode live n'est pas activé, le tableau de bord, la page de configuration et la liste des transactions affichent tous les trois le même avertissement que le module Stripe officiel. Impossible d'oublier qu'on travaille en mode test.&lt;br /&gt;
&lt;br /&gt;
=== Menus ===&lt;br /&gt;
&lt;br /&gt;
Tout est regroupé sous '''Banques et caisses → Compte Stripe''' (menu du module officiel), à plat, en trois entrées de même niveau :&lt;br /&gt;
&lt;br /&gt;
# Tableau de bord Stripe&lt;br /&gt;
# Transactions Stripe&lt;br /&gt;
# Import CSV ''(réservé aux administrateurs)''&lt;br /&gt;
&lt;br /&gt;
Un lien vers le tableau de bord est aussi ajouté automatiquement sur la fiche du compte bancaire configuré comme compte Stripe.&lt;br /&gt;
&lt;br /&gt;
== 9. Tâche planifiée ==&lt;br /&gt;
&lt;br /&gt;
Deux façons d'exécuter la synchronisation, toutes deux idempotentes et sans risque à relancer. Dans les deux cas le code exécuté est strictement le même : aucune divergence de comportement.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #d33; background:#fee7e6; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''⚠ Aucune des deux ne démarre toute seule.'''&lt;br /&gt;
&lt;br /&gt;
L'activation du module crée la tâche &amp;lt;code&amp;gt;StripeAccountingSync&amp;lt;/code&amp;gt;, mais '''désactivée par défaut'''. Et même activée, l'ordonnanceur Dolibarr n'est déclenché par rien tant qu'aucune crontab système ne l'appelle. Sans ces deux étapes, la synchro n'a lieu qu'au clic manuel sur « Synchroniser maintenant ».&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Étape 1 — activer la tâche ===&lt;br /&gt;
&lt;br /&gt;
Dans '''Accueil → Configuration → Modules → Tâches planifiées'''. &amp;lt;code&amp;gt;llx_cronjob&amp;lt;/code&amp;gt; étant une table du cœur, ce réglage se fait uniquement par l'interface, jamais en SQL direct depuis le module.&lt;br /&gt;
&lt;br /&gt;
=== Étape 2 — un déclencheur système ===&lt;br /&gt;
&lt;br /&gt;
Au choix, l'une des deux options.&lt;br /&gt;
&lt;br /&gt;
'''Option A — ordonnanceur Dolibarr''' ''(recommandé si plusieurs tâches planifiées coexistent)''. Lance toutes les tâches dues, pas seulement celle-ci. Nécessite l'étape 1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
*/15 * * * * curl &amp;quot;https://votre-dolibarr/public/cron/cron_run_jobs_by_url.php?securitykey=VOTRE_CLE&amp;amp;userlogin=VOTRE_LOGIN&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La clé de sécurité se génère sur la page des tâches planifiées, bouton « Sécurité de l'exécution des tâches par URL ».&lt;br /&gt;
&lt;br /&gt;
'''Option B — script CLI du module.''' Autonome, refuse l'exécution depuis un navigateur, et indépendant de l'état activé ou non de la tâche Dolibarr.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
*/15 * * * * php /chemin/vers/htdocs/custom/stripeaccounting/cron/stripe_sync.php &amp;gt;&amp;gt; /var/log/stripeaccounting.log 2&amp;gt;&amp;amp;1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 10. Journalisation et permissions ==&lt;br /&gt;
&lt;br /&gt;
=== Journalisation ===&lt;br /&gt;
&lt;br /&gt;
Chaque appel API, écriture générée, avertissement ou erreur est tracé dans &amp;lt;code&amp;gt;llx_stripeaccounting_log&amp;lt;/code&amp;gt;, consultable en base ou via le fichier de log standard Dolibarr. Niveaux : &amp;lt;code&amp;gt;DEBUG&amp;lt;/code&amp;gt; &amp;lt; &amp;lt;code&amp;gt;INFO&amp;lt;/code&amp;gt; &amp;lt; &amp;lt;code&amp;gt;WARNING&amp;lt;/code&amp;gt; &amp;lt; &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt;. La colonne &amp;lt;code&amp;gt;context&amp;lt;/code&amp;gt; contient le détail structuré en JSON (payload API, montants calculés…).&lt;br /&gt;
&lt;br /&gt;
=== Permissions ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Droit !! Contrôle&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;read&amp;lt;/code&amp;gt; || Consultation du tableau de bord et de la liste&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;write&amp;lt;/code&amp;gt; || Déclarée pour la configuration, mais non vérifiée dans le code aujourd'hui&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;reconcile&amp;lt;/code&amp;gt; || Déclenchement manuel de la synchronisation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
En pratique, &amp;lt;code&amp;gt;admin/setup.php&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;import.php&amp;lt;/code&amp;gt; ne contrôlent que le statut '''administrateur Dolibarr''', pas le droit &amp;lt;code&amp;gt;write&amp;lt;/code&amp;gt; : seuls les administrateurs peuvent configurer le module ou importer un CSV, quoi qu'il soit coché dans les permissions.&lt;br /&gt;
&lt;br /&gt;
== 11. Base de données ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;llx_stripeaccounting_transaction&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Une ligne par objet Stripe traité — charge, frais, remboursement, litige ou virement — tous dans la même table, distingués par la colonne &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:24%;&amp;quot; | Colonne !! style=&amp;quot;width:16%;&amp;quot; | Type !! Rôle&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rowid&amp;lt;/code&amp;gt; || int AI || Clé primaire&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;entity&amp;lt;/code&amp;gt; || int || Multi-société Dolibarr&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_object_id&amp;lt;/code&amp;gt; || varchar(80) || Identifiant Stripe — '''ancre d'idempotence'''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_event_id&amp;lt;/code&amp;gt; || varchar(80) || Identifiant d'évènement, informatif seulement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt; || varchar(20) || &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;refund&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;dispute&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;other&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_source_id&amp;lt;/code&amp;gt; || varchar(80) || Objet Stripe source (ex. la charge liée à un remboursement)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;source_label&amp;lt;/code&amp;gt; || varchar(80) || Libellé libre saisi à l'import CSV ; vide pour les lignes venues de l'API&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;description&amp;lt;/code&amp;gt; || varchar(255) || Libellé Stripe&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;amount&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;net&amp;lt;/code&amp;gt; || decimal(24,8) || Montants déjà convertis depuis les centimes Stripe&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;currency&amp;lt;/code&amp;gt; || varchar(3) || Code devise ISO&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;date_created&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;date_available_on&amp;lt;/code&amp;gt; || datetime || Dates côté Stripe&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_facture&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fk_paiement&amp;lt;/code&amp;gt; || int || Facture et paiement Dolibarr résolus, si trouvés&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; || int || Ligne &amp;lt;code&amp;gt;llx_bank&amp;lt;/code&amp;gt; générée ''(vide pour un frais en mode TVA &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt;)''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;piece_num&amp;lt;/code&amp;gt; || varchar(20) || Numéro de pièce comptable généré, quand il y en a un&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt; || varchar(16) || &amp;lt;code&amp;gt;pending&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ignored&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;error_message&amp;lt;/code&amp;gt; || text || Détail en cas d'erreur&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;date_creation&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;date_processed&amp;lt;/code&amp;gt; || datetime || Horodatage technique&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_user_creat&amp;lt;/code&amp;gt; || int || Utilisateur ayant déclenché le traitement&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Clé unique''' sur &amp;lt;code&amp;gt;(stripe_object_id, entity)&amp;lt;/code&amp;gt; — c'est elle qui garantit qu'un même objet Stripe ne peut jamais être inséré deux fois, même en cas d'exécutions concurrentes.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;llx_stripeaccounting_log&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Colonne !! Rôle&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;level&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;DEBUG&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;INFO&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;WARNING&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;message&amp;lt;/code&amp;gt; || Message court&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;context&amp;lt;/code&amp;gt; || Contexte structuré en JSON&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_stripeaccounting_transaction&amp;lt;/code&amp;gt; || Transaction liée, si applicable&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;datec&amp;lt;/code&amp;gt; || Horodatage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 12. Dépannage ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:26%;&amp;quot; | Symptôme !! Cause probable !! Action&lt;br /&gt;
|-&lt;br /&gt;
| Le bouton « Synchroniser maintenant » est désactivé || Configuration minimale incomplète || Compléter les champs listés dans le bandeau d'alerte de la page de configuration&lt;br /&gt;
|-&lt;br /&gt;
| Une transaction reste en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; || Écriture refusée par Dolibarr (compte inexistant, période clôturée), ou remboursement non rattaché || Lire &amp;lt;code&amp;gt;error_message&amp;lt;/code&amp;gt; sur la ligne, puis le détail dans la table de logs&lt;br /&gt;
|-&lt;br /&gt;
| Le solde Stripe ne s'affiche pas || Clé API manquante ou invalide dans le module Stripe officiel || Vérifier &amp;lt;code&amp;gt;stripe/admin/stripe.php&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Un remboursement n'est jamais rapproché || Le paiement d'origine n'a pas été retrouvé via &amp;lt;code&amp;gt;ext_payment_id&amp;lt;/code&amp;gt; || Vérifier que le paiement Stripe a bien été enregistré par le module officiel avec cet identifiant&lt;br /&gt;
|-&lt;br /&gt;
| Un &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt; reste en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; || Tiers fournisseur Stripe non renseigné, ou sans code comptable fournisseur || Renseigner le champ en configuration, et compléter la fiche du tiers&lt;br /&gt;
|-&lt;br /&gt;
| Un remboursement importé en CSV reste en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; || '''Normal et attendu''' — ce compte n'est pas relié à &amp;lt;code&amp;gt;ext_payment_id&amp;lt;/code&amp;gt; || Traiter la facture et le remboursement manuellement en comptabilité&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 13. Pièges rencontrés ==&lt;br /&gt;
&lt;br /&gt;
Notes de développement, conservées pour éviter de retomber dedans.&lt;br /&gt;
&lt;br /&gt;
* '''&amp;lt;code&amp;gt;PaymentVarious::create()&amp;lt;/code&amp;gt;''' ne met à jour &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; qu'en base, jamais sur l'objet PHP. Un &amp;lt;code&amp;gt;fetch()&amp;lt;/code&amp;gt; après &amp;lt;code&amp;gt;create()&amp;lt;/code&amp;gt; est indispensable pour récupérer la vraie valeur.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;select_comptes()&amp;lt;/code&amp;gt;''' affiche son propre HTML ''et'' retourne le nombre de comptes. L'appeler en instruction nue : l'envelopper dans &amp;lt;code&amp;gt;print&amp;lt;/code&amp;gt; réafficherait ce nombre juste après la balise select.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;master.inc.php&amp;lt;/code&amp;gt;, pas &amp;lt;code&amp;gt;main.inc.php&amp;lt;/code&amp;gt;''' pour le script CLI. Le second attend une session HTTP et, en pur CLI, se termine silencieusement — aucune sortie, aucun log, code retour 0 — dans sa redirection vers la page de connexion. L'impression trompeuse que le script « ne fait rien » plutôt qu'une vraie erreur.&lt;br /&gt;
* '''Bibliothèques du cœur''' — &amp;lt;code&amp;gt;master.inc.php&amp;lt;/code&amp;gt; ne charge pas tout ce que &amp;lt;code&amp;gt;main.inc.php&amp;lt;/code&amp;gt; charge pour le web (par exemple &amp;lt;code&amp;gt;core/lib/date.lib.php&amp;lt;/code&amp;gt;, requis par &amp;lt;code&amp;gt;BookKeeping&amp;lt;/code&amp;gt;). À inclure explicitement si le script CLI évolue.&lt;br /&gt;
* '''Option « rien sélectionné » à &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;''' dans les sélecteurs de compte comptable — voir la section Configuration.&lt;br /&gt;
&lt;br /&gt;
== 14. Limites connues ==&lt;br /&gt;
&lt;br /&gt;
* '''Devises « zéro décimale »''' (JPY, KRW…) non gérées : les montants sont divisés par 100 en supposant deux décimales. Usage prévu : EUR.&lt;br /&gt;
* '''Fenêtre de 35 jours''' non configurable. Une synchronisation interrompue plus longtemps devra être rattrapée manuellement.&lt;br /&gt;
* '''Rattachement des remboursements''' — dépend de &amp;lt;code&amp;gt;ext_payment_id&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;ext_payment_site&amp;lt;/code&amp;gt; sur &amp;lt;code&amp;gt;llx_paiement&amp;lt;/code&amp;gt;, renseignés par le flux de paiement Stripe standard. Un paiement enregistré autrement ne pourra pas être rattaché automatiquement. Le rattachement se fait via le '''PaymentIntent id''', jamais via l'id de charge : le module Stripe du cœur ne stocke jamais ce dernier ''(il y met soit le PaymentIntent brut, soit un composite, selon le chemin de paiement emprunté)''.&lt;br /&gt;
* '''Import CSV en notation française''' uniquement : un export à point décimal ne serait pas interprété correctement.&lt;br /&gt;
* '''Colonne « Transfer » du CSV Paiements''' stockée à titre informatif seulement : elle ne sert pas à vérifier que le total des paiements correspond au montant du virement importé.&lt;br /&gt;
* '''Remboursements importés en CSV toujours en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;''' — comportement voulu, pas un bug.&lt;br /&gt;
* '''Mode TVA &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt;''' — le solde bancaire du compte Stripe ne reflète pas les frais, voir section 5.&lt;br /&gt;
&lt;br /&gt;
[[Catégorie:Dolibarr]]&lt;br /&gt;
[[Catégorie:Modules]]&lt;br /&gt;
[[Catégorie:Comptabilité]]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Fichier:Fr.png&amp;diff=548</id>
		<title>Fichier:Fr.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Fichier:Fr.png&amp;diff=548"/>
				<updated>2026-08-02T12:33:33Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Fichier:Us.png&amp;diff=547</id>
		<title>Fichier:Us.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Fichier:Us.png&amp;diff=547"/>
				<updated>2026-08-02T12:33:19Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Stripeaccounting/en&amp;diff=546</id>
		<title>Stripeaccounting/en</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Stripeaccounting/en&amp;diff=546"/>
				<updated>2026-08-02T12:22:42Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:StripeAccounting — Technical documentation}}&lt;br /&gt;
&lt;br /&gt;
[[Stripeaccounting]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border:1px solid #c8ccd1; background:#f8f9fa; border-radius:4px; padding:1em 1.2em; margin:0 0 1.5em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''StripeAccounting''' is a Dolibarr module for '''Stripe accounting reconciliation'''.&lt;br /&gt;
&lt;br /&gt;
It reads the Stripe API (or a CSV export), identifies the movements the official Stripe module does not post — fees, refunds, disputes, payouts — and creates the missing accounting entries.&lt;br /&gt;
&lt;br /&gt;
: '''Compatibility''' — Dolibarr 17+, PHP 7.2 → 8.5&lt;br /&gt;
: '''Depends on''' — Stripe, Bank and Double-entry Accounting modules&lt;br /&gt;
: '''See also''' — [[README|Installation and user guide]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== 1. Design principles ==&lt;br /&gt;
&lt;br /&gt;
Four rules govern the whole module.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:22%;&amp;quot; | Principle !! What it means&lt;br /&gt;
|-&lt;br /&gt;
| '''Complementary''' || The module creates no payment, no invoice, no webhook. It reads Stripe and completes the books, nothing more.&lt;br /&gt;
|-&lt;br /&gt;
| '''Idempotent''' || Each Stripe object is processed once only, no matter how many times the sync is re-run.&lt;br /&gt;
|-&lt;br /&gt;
| '''Never guess''' || If an operation cannot be matched with certainty, nothing is posted: the row goes to &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; for manual review.&lt;br /&gt;
|-&lt;br /&gt;
| '''Configuration is blocking''' || As long as the minimum configuration is incomplete, no sync runs at all (no button, no cron, no import).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2. Requirements ==&lt;br /&gt;
&lt;br /&gt;
=== Required Dolibarr modules ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Module !! What it provides&lt;br /&gt;
|-&lt;br /&gt;
| '''Stripe''' (&amp;lt;code&amp;gt;modStripe&amp;lt;/code&amp;gt;) || API key, test/live mode, Stripe financial account&lt;br /&gt;
|-&lt;br /&gt;
| '''Bank''' (&amp;lt;code&amp;gt;modBanque&amp;lt;/code&amp;gt;) || &amp;lt;code&amp;gt;llx_bank&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;llx_bank_account&amp;lt;/code&amp;gt; tables&lt;br /&gt;
|-&lt;br /&gt;
| '''Double-entry accounting''' (&amp;lt;code&amp;gt;modAccounting&amp;lt;/code&amp;gt;) || &amp;lt;code&amp;gt;llx_accounting_bookkeeping&amp;lt;/code&amp;gt; table&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Mandatory Dolibarr setting ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ACCOUNTING_ACCOUNT_TRANSFER_CASH&amp;lt;/code&amp;gt; must be set under '''Accounting → Setup → Miscellaneous accounts'''. Without it, the internal transfer generated by payouts cannot be transferred to accounting (a Dolibarr limitation, not a module one).&lt;br /&gt;
&lt;br /&gt;
=== Notes ===&lt;br /&gt;
&lt;br /&gt;
* The Stripe PHP SDK is not re-vendored: the module reuses the core copy (&amp;lt;code&amp;gt;includes/stripe/stripe-php/&amp;lt;/code&amp;gt;).&lt;br /&gt;
* The code deliberately avoids any PHP syntax newer than 7.2 (no &amp;lt;code&amp;gt;match&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;?-&amp;gt;&amp;lt;/code&amp;gt;, enums, typed properties, &amp;lt;code&amp;gt;str_contains&amp;lt;/code&amp;gt;…) so it runs across the whole 7.2 → 8.5 range.&lt;br /&gt;
&lt;br /&gt;
== 3. File tree ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
custom/stripeaccounting/&lt;br /&gt;
├── core/modules/modStripeAccounting.class.php   Module descriptor (permissions, menus, cron, constants)&lt;br /&gt;
├── class/&lt;br /&gt;
│   ├── StripeApi.class.php                      Stripe SDK wrapper (read-only)&lt;br /&gt;
│   ├── StripeRepository.class.php               SQL access + idempotency&lt;br /&gt;
│   ├── StripeLogger.class.php                   Logging&lt;br /&gt;
│   ├── StripeAccounting.class.php               Accounting entry generation&lt;br /&gt;
│   ├── StripePayout.class.php                   Payout reconciliation&lt;br /&gt;
│   ├── StripeSync.class.php                     Orchestrator (cron entry point)&lt;br /&gt;
│   ├── StripeCsvImporter.class.php              CSV import&lt;br /&gt;
│   └── actions_stripeaccounting.class.php       'bankcard' hook&lt;br /&gt;
├── admin/setup.php                              Configuration&lt;br /&gt;
├── import.php                                   CSV import&lt;br /&gt;
├── dashboard.php                                Dashboard&lt;br /&gt;
├── transaction_list.php                         Transaction list&lt;br /&gt;
├── cron/stripe_sync.php                         CLI entry point&lt;br /&gt;
├── lib/stripeaccounting.lib.php&lt;br /&gt;
├── sql/&lt;br /&gt;
├── langs/{fr_FR,en_US,es_ES,it_IT,de_DE}/&lt;br /&gt;
└── css/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dependency direction ===&lt;br /&gt;
&lt;br /&gt;
: pages and hook → &amp;lt;code&amp;gt;StripeSync&amp;lt;/code&amp;gt; → (&amp;lt;code&amp;gt;StripeApi&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StripeRepository&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StripeAccounting&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StripePayout&amp;lt;/code&amp;gt;) → &amp;lt;code&amp;gt;StripeLogger&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:26%;&amp;quot; | Class !! Role&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeApi&amp;lt;/code&amp;gt; || Queries the Stripe SDK (balance transactions, charges, refunds, disputes, payouts) with automatic pagination. No database access, no accounting entries.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeRepository&amp;lt;/code&amp;gt; || All SQL for the module's two tables. &amp;lt;code&amp;gt;upsertTransaction()&amp;lt;/code&amp;gt; is the idempotency anchor.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeLogger&amp;lt;/code&amp;gt; || Writes to &amp;lt;code&amp;gt;llx_stripeaccounting_log&amp;lt;/code&amp;gt; and mirrors to &amp;lt;code&amp;gt;dol_syslog()&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeAccounting&amp;lt;/code&amp;gt; || Builds accounting entries (refund, dispute, reverse-charge VAT) or bank movements (fees). Exposes &amp;lt;code&amp;gt;checkConfig()&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripePayout&amp;lt;/code&amp;gt; || Creates the internal bank transfer between the Stripe account and the real bank account.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeSync&amp;lt;/code&amp;gt; || Orchestrator: one method per flow, plus &amp;lt;code&amp;gt;reconcileStripeAccount()&amp;lt;/code&amp;gt; which chains them all.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeCsvImporter&amp;lt;/code&amp;gt; || Feeds the same pipeline from a Stripe CSV export.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ActionsStripeAccounting&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;bankcard&amp;lt;/code&amp;gt; hook: dashboard link on the Stripe account record.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 4. Synchronisation and idempotency ==&lt;br /&gt;
&lt;br /&gt;
Every flow (&amp;lt;code&amp;gt;syncFees&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncRefunds&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncDisputes&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncPayouts&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncTransactions&amp;lt;/code&amp;gt;) always follows the same steps:&lt;br /&gt;
&lt;br /&gt;
# '''Check the configuration''' — if incomplete: &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt; log, immediate stop, no API call at all.&lt;br /&gt;
# '''List Stripe objects''' over a rolling window of '''35 days'''.&lt;br /&gt;
# '''Filter''' — an object is skipped only if it already exists ''and'' its status is &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;ignored&amp;lt;/code&amp;gt;. A row in &amp;lt;code&amp;gt;pending&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; is '''retried''' on this run.&lt;br /&gt;
# '''Record''' it as &amp;lt;code&amp;gt;pending&amp;lt;/code&amp;gt;, then generate the accounting entry or bank movement.&lt;br /&gt;
# '''Conclude''' — success: status &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt;. Failure: status &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; with the message, and '''the batch carries on''' with the next object.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #36c; background:#eaf3ff; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Automatic retry''' — a row in &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; becomes eligible again on the next run. Once the cause is fixed (a fiscal year created late, for instance), no manual action is needed.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Why duplicates are impossible ===&lt;br /&gt;
&lt;br /&gt;
* '''Unique database key''' on &amp;lt;code&amp;gt;(stripe_object_id, entity)&amp;lt;/code&amp;gt; — protects even against two concurrent cron executions.&lt;br /&gt;
* '''Explicit check before processing''' — avoids even attempting to post an entry for an already-finalised object.&lt;br /&gt;
&lt;br /&gt;
=== Special cases: &amp;lt;code&amp;gt;adjustment&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;payment_failure_refund&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
These are balance corrections Stripe makes on its own (reversal after a dispute is resolved, automatic refund of a payment that ultimately failed). The module '''records''' them — otherwise they would stay invisible — but '''never''' posts them automatically: the sign of the amount and the underlying cause vary too much. They are created directly in &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, with an explicit message, to be handled manually.&lt;br /&gt;
&lt;br /&gt;
== 5. Accounting entries ==&lt;br /&gt;
&lt;br /&gt;
All lines of a single Stripe event share the same &amp;lt;code&amp;gt;doc_type='stripeaccounting'&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fk_doc&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;doc_ref&amp;lt;/code&amp;gt; triplet: Dolibarr automatically groups them under one piece number, so the module needs no numbering scheme of its own.&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! Event !! What the module does !! Resulting entry&lt;br /&gt;
|-&lt;br /&gt;
| Stripe fee ''(VAT mode &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt;)'' || &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; bank movement || 627xxx / 517xxx entry generated later by Dolibarr&lt;br /&gt;
|-&lt;br /&gt;
| Stripe fee ''(&amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt; mode)'' || Plus: VAT pair posted immediately || Debit deductible VAT, credit reverse-charge VAT ''(net impact nil)''&lt;br /&gt;
|-&lt;br /&gt;
| Stripe fee ''(&amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; mode)'' || Full direct entry || Debit fee account excl. VAT + deductible VAT, credit Stripe account incl. VAT&lt;br /&gt;
|-&lt;br /&gt;
| Subscription / service fees ''(Radar, Billing, Connect…)'' || &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; bank movement || Entry generated later by Dolibarr, on the Stripe supplier account&lt;br /&gt;
|-&lt;br /&gt;
| Payout || Internal bank transfer between the two accounts || Entry generated later by Dolibarr&lt;br /&gt;
|-&lt;br /&gt;
| Refund ''(invoice found)'' || Direct entry || Debit customer account 411xxx, credit Stripe account 517xxx&lt;br /&gt;
|-&lt;br /&gt;
| Refund ''(invoice not found)'' || Nothing || Status &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, handle manually&lt;br /&gt;
|-&lt;br /&gt;
| Dispute / chargeback || Direct entry || Debit dispute loss 658xxx, credit Stripe account 517xxx ''(+ fee account if fees apply)''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Why fees and payouts produce no direct entry ===&lt;br /&gt;
&lt;br /&gt;
The historical problem: when a Stripe-paid invoice is transferred to accounting through Dolibarr's standard workflow, the payment is posted at its '''gross''' amount — fees are ignored at that stage.&lt;br /&gt;
&lt;br /&gt;
If the module posted its own entry ''and'' its own bank line on top of that, this line would stay invisible to &amp;lt;code&amp;gt;bankjournal.php&amp;lt;/code&amp;gt; — which only recognises lines attached to &amp;lt;code&amp;gt;doc_type='bank'&amp;lt;/code&amp;gt;. An administrator transferring the bank account to accounting &amp;quot;normally&amp;quot; would then create a '''second''' entry for the very same movement.&lt;br /&gt;
&lt;br /&gt;
'''The chosen solution:''' for fees, subscription fees and payouts, the module now creates only the '''real bank movement''', using Dolibarr's native mechanisms. The native ''&amp;quot;Transfer to accounting&amp;quot;'' button then produces the entry, exactly as for any other bank movement. In those three cases, the module no longer touches &amp;lt;code&amp;gt;llx_accounting_bookkeeping&amp;lt;/code&amp;gt; at all.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:22%;&amp;quot; | Case !! Native mechanism used&lt;br /&gt;
|-&lt;br /&gt;
| Fees and subscription fees || &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; (bank movement with an explicit counterpart account, no third party or invoice), carrying its own &amp;lt;code&amp;gt;accountancy_code&amp;lt;/code&amp;gt;, which &amp;lt;code&amp;gt;bankjournal.php&amp;lt;/code&amp;gt; reads directly.&lt;br /&gt;
|-&lt;br /&gt;
| Payouts || Dolibarr internal transfer: &amp;lt;code&amp;gt;Account::addline()&amp;lt;/code&amp;gt; on both sides, plus &amp;lt;code&amp;gt;add_url_line(…, 'banktransfert')&amp;lt;/code&amp;gt;. The counterpart is posted to &amp;lt;code&amp;gt;ACCOUNTING_ACCOUNT_TRANSFER_CASH&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In both cases the status becomes &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt; — the module's job is done — but '''&amp;lt;code&amp;gt;piece_num&amp;lt;/code&amp;gt; stays empty''': the entry does not exist yet, only &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; is set. After the manual transfer, it can be found with &amp;lt;code&amp;gt;doc_type='bank'&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;fk_doc&amp;lt;/code&amp;gt; equal to the row's &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #fc3; background:#fef6e7; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Worth knowing''' — the payout entry only balances to zero on the transfer account once '''both''' bank accounts (Stripe ''and'' the real bank) have been transferred to accounting, not just one of them.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #d33; background:#fee7e6; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''⚠ &amp;lt;code&amp;gt;STRIPE_AUTO_RECORD_PAYOUT&amp;lt;/code&amp;gt; must stay disabled'''&lt;br /&gt;
&lt;br /&gt;
Once this module handles payouts, untick &amp;quot;Enable automatic recording of Stripe payments&amp;quot; in &amp;lt;code&amp;gt;stripe/admin/stripe.php&amp;lt;/code&amp;gt; — despite its wording, that checkbox only concerns payouts.&lt;br /&gt;
&lt;br /&gt;
Otherwise the official module's webhook and this module would each create their own bank movement for the same payout, unaware of each other.&lt;br /&gt;
&lt;br /&gt;
The core webhook keeps '''no''' trace of the payout id it has processed: should Stripe deliver the event twice (delivery is guaranteed &amp;quot;at least once&amp;quot;), nothing stops it from duplicating on its own either. This module has real idempotency and automatically catches up any missed payout within 35 days.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The &amp;quot;Stripe transfers&amp;quot; page is hidden ===&lt;br /&gt;
&lt;br /&gt;
On activation, &amp;lt;code&amp;gt;modStripeAccounting::init()&amp;lt;/code&amp;gt; disables the &amp;lt;code&amp;gt;stripe/payout.php&amp;lt;/code&amp;gt; menu entry: that page queries the API live without recording anything, and having it alongside this module would only create confusion about which one is authoritative for payouts. &amp;lt;code&amp;gt;remove()&amp;lt;/code&amp;gt; restores the original condition. '''This is the only core table the module modifies''' — deliberate, and documented here for that reason.&lt;br /&gt;
&lt;br /&gt;
=== Per-transaction fees or subscription fees? ===&lt;br /&gt;
&lt;br /&gt;
Stripe bills two distinct things under the generic word &amp;quot;fees&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! !! Per-transaction fees !! Subscription / service fees&lt;br /&gt;
|-&lt;br /&gt;
! Example&lt;br /&gt;
| Commission on each payment || Radar, Billing, Connect&lt;br /&gt;
|-&lt;br /&gt;
! Where to find it&lt;br /&gt;
| The &amp;lt;code&amp;gt;.fee&amp;lt;/code&amp;gt; field of a &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; balance transaction || A dedicated balance transaction, type &amp;lt;code&amp;gt;stripe_fee&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;application_fee&amp;lt;/code&amp;gt; ''(its &amp;lt;code&amp;gt;.fee&amp;lt;/code&amp;gt; is always 0, the amount sits in &amp;lt;code&amp;gt;.amount&amp;lt;/code&amp;gt;)''&lt;br /&gt;
|-&lt;br /&gt;
! Account used&lt;br /&gt;
| The configured fee account (627xxx) || The supplier accounting code of the configured Stripe third party&lt;br /&gt;
|-&lt;br /&gt;
! Type in database&lt;br /&gt;
| &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Limitation of the &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; VAT mode ===&lt;br /&gt;
&lt;br /&gt;
This mode has to split the gross amount into net + VAT, something &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; cannot express. It therefore keeps the previous behaviour: a full direct entry, with no bank movement created. No duplicate risk (precisely because no bank line is produced), but the &amp;lt;code&amp;gt;llx_bank&amp;lt;/code&amp;gt; balance of the Stripe account will never reflect the fees while this mode is active.&lt;br /&gt;
&lt;br /&gt;
== 6. CSV import ==&lt;br /&gt;
&lt;br /&gt;
The import covers the case of a Stripe account '''different''' from the one configured in the official module — another PrestaShop shop with its own merchant account, for example. The API has no access to it: its contents are exported to CSV from the Stripe dashboard, then imported.&lt;br /&gt;
&lt;br /&gt;
=== Starting assumption ===&lt;br /&gt;
&lt;br /&gt;
The invoices and payments of that shop are '''already''' posted in Dolibarr through some other process, and the collection (debit 517, credit 411) is already booked. Only the '''fees''', '''refunds''' and '''payouts''' are missing — which is exactly what the import handles.&lt;br /&gt;
&lt;br /&gt;
=== Interface: a single field ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;import.php&amp;lt;/code&amp;gt; now exposes only one upload field, '''General history''', wired to &amp;lt;code&amp;gt;importGeneralHistory()&amp;lt;/code&amp;gt;. That file alone covers every movement type.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;importPayments()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;importPayouts()&amp;lt;/code&amp;gt; are still implemented and functional, but no longer reachable from the interface; they are documented below for reference.&lt;br /&gt;
&lt;br /&gt;
Like the &amp;quot;Sync now&amp;quot; button, the import is blocked — warning banner, disabled button, server-side guard — while the configuration is incomplete.&lt;br /&gt;
&lt;br /&gt;
=== The three methods ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:24%;&amp;quot; | Method !! Stripe export read !! Processing&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;importGeneralHistory()&amp;lt;/code&amp;gt;&amp;lt;br /&amp;gt;''(the only one exposed)'' || Balance history || Dispatch on the &amp;lt;code&amp;gt;Type&amp;lt;/code&amp;gt; column, see table below&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;importPayments()&amp;lt;/code&amp;gt; || Payments || Fee → fee movement. Amount refunded → &amp;lt;code&amp;gt;refund&amp;lt;/code&amp;gt; row, always in &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;importPayouts()&amp;lt;/code&amp;gt; || Payouts || Exactly the same processing as a payout coming from the API&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
General history dispatch, by &amp;lt;code&amp;gt;Type&amp;lt;/code&amp;gt; column:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:30%;&amp;quot; | Stripe type !! Processing&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt; || Internal bank transfer, as via the API&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;payment&amp;lt;/code&amp;gt; with a fee || Fee movement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_fee&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;application_fee&amp;lt;/code&amp;gt; || Subscription fee, on the Stripe supplier account&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;refund&amp;lt;/code&amp;gt; || Recorded, '''always''' in &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;payout_minimum_balance_hold&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;…_release&amp;lt;/code&amp;gt; || '''Ignored''' — Stripe rolling reserve, no real cash movement, nothing to post&lt;br /&gt;
|-&lt;br /&gt;
| any other type || Recorded as &amp;lt;code&amp;gt;type='other'&amp;lt;/code&amp;gt;, status &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, raw Stripe type kept in the description. No guessed entry.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Columns are matched '''by name''': their order does not matter, and extra unused columns are ignored.&lt;br /&gt;
&lt;br /&gt;
=== Import idempotency ===&lt;br /&gt;
&lt;br /&gt;
The unique key protects against any double import: re-importing the same CSV, or one overlapping a previous import, creates no duplicate.&lt;br /&gt;
&lt;br /&gt;
An important detail: in the general history, &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;payment&amp;lt;/code&amp;gt; rows are indexed by their '''&amp;lt;code&amp;gt;Source&amp;lt;/code&amp;gt;''' column (&amp;lt;code&amp;gt;po_…&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ch_…&amp;lt;/code&amp;gt;), not by the row's own &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;txn_…&amp;lt;/code&amp;gt;) — the very same key the dedicated imports use. Importing the general history '''on top of''' the specific exports therefore never posts the same entry twice, in any order.&lt;br /&gt;
&lt;br /&gt;
Since Stripe identifiers are unique platform-wide, mixing rows from the API account and from several CSV-imported accounts in the same table carries no collision risk.&lt;br /&gt;
&lt;br /&gt;
=== Practical details ===&lt;br /&gt;
&lt;br /&gt;
* '''Source label''' — a free-text field entered at import time (e.g. &amp;quot;DRM shop&amp;quot;) is stored on every created row and serves as a column and filter in the list, to tell several shops apart side by side.&lt;br /&gt;
* '''Amount format''' — Stripe CSVs use the French decimal comma, converted through &amp;lt;code&amp;gt;price2num()&amp;lt;/code&amp;gt;. Dates marked &amp;lt;code&amp;gt;(UTC)&amp;lt;/code&amp;gt; are interpreted as such.&lt;br /&gt;
&lt;br /&gt;
== 7. Configuration ==&lt;br /&gt;
&lt;br /&gt;
The API key and test/live mode are '''not''' re-entered here: they are read, read-only, from the official Stripe module.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:26%;&amp;quot; | Field !! Constant !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| Stripe financial account || &amp;lt;code&amp;gt;STRIPE_BANK_ACCOUNT_FOR_PAYMENTS&amp;lt;/code&amp;gt; ''(official module constant)'' || Bank account selector. No local copy, hence no risk of divergence.&lt;br /&gt;
|-&lt;br /&gt;
| Main bank account || &amp;lt;code&amp;gt;STRIPE_BANK_ACCOUNT_FOR_BANKTRANSFERS&amp;lt;/code&amp;gt; ''(official module constant)'' || Same selector. See the box below.&lt;br /&gt;
|-&lt;br /&gt;
| Fee account || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_FRAIS&amp;lt;/code&amp;gt; || Account number, e.g. 627xxx&lt;br /&gt;
|-&lt;br /&gt;
| Dispute account || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_LITIGES&amp;lt;/code&amp;gt; || Account number, e.g. 658xxx. '''Required''' — used as soon as a dispute occurs, whatever the VAT mode.&lt;br /&gt;
|-&lt;br /&gt;
| Stripe supplier third party || &amp;lt;code&amp;gt;STRIPEACCOUNTING_FOURNISSEUR_STRIPE_ID&amp;lt;/code&amp;gt; || A third party flagged as supplier; its supplier accounting code is what gets used. Optional, unless subscription fees exist.&lt;br /&gt;
|-&lt;br /&gt;
| VAT mode || &amp;lt;code&amp;gt;STRIPEACCOUNTING_VAT_MODE&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Deductible VAT account (intra-EU) || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_TVA_DEDUCTIBLE&amp;lt;/code&amp;gt; || Required when the VAT mode is not &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt;. Stripe always invoices from a non-French EU entity, so the deductible VAT is intra-EU in every case.&lt;br /&gt;
|-&lt;br /&gt;
| VAT due account (intra-EU) || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_TVA_AUTOLIQUIDATION&amp;lt;/code&amp;gt; || Required in &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt; mode only — never used in &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; mode.&lt;br /&gt;
|-&lt;br /&gt;
| VAT rate || &amp;lt;code&amp;gt;STRIPEACCOUNTING_VAT_RATE&amp;lt;/code&amp;gt; || Percentage, 20 by default&lt;br /&gt;
|-&lt;br /&gt;
| Sync frequency || &amp;lt;code&amp;gt;STRIPEACCOUNTING_SYNC_UNITFREQUENCY&amp;lt;/code&amp;gt; || Applied to the scheduled job (in seconds)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #36c; background:#eaf3ff; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Why redefine the main bank account here?'''&lt;br /&gt;
&lt;br /&gt;
The official Stripe module's setup page only renders that field when &amp;lt;code&amp;gt;STRIPE_AUTO_RECORD_PAYOUT&amp;lt;/code&amp;gt; is enabled — and its own save handler resets the value to 0 on every save while the field is not rendered. Yet that setting must stay disabled once this module handles payouts. The field is therefore re-exposed here, writing the core constant directly, so the value stays configurable and stable.&lt;br /&gt;
&lt;br /&gt;
Both account selectors only write their constant when a real account was submitted: saving the page for some unrelated field never overwrites a correct value.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Configuration check ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;StripeAccounting::checkConfig()&amp;lt;/code&amp;gt; returns the list of missing constants. It is called both by the setup page (information banner) and by every sync entry point (the real guard that blocks all processing).&lt;br /&gt;
&lt;br /&gt;
=== Pitfall with accounting account selectors ===&lt;br /&gt;
&lt;br /&gt;
The four fields using &amp;lt;code&amp;gt;FormAccounting::select_account()&amp;lt;/code&amp;gt; (fees, disputes, both VAT accounts) have a &amp;quot;nothing selected&amp;quot; option whose value is '''&amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;''' — a non-empty string, therefore truthy in PHP. A field left blank and saved literally stores &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;StripeAccounting::getAccountConst()&amp;lt;/code&amp;gt; normalises that value to an empty string on read, everywhere these constants are read. No entry can therefore land on the non-existent account &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 8. User interface ==&lt;br /&gt;
&lt;br /&gt;
=== Dashboard ===&lt;br /&gt;
&lt;br /&gt;
Stripe balance (live API call), number of unreconciled transactions, total fees for the month, pending payouts, and a '''Sync now''' button — disabled, with a banner listing the missing constants, while the configuration is incomplete.&lt;br /&gt;
&lt;br /&gt;
=== Transaction list ===&lt;br /&gt;
&lt;br /&gt;
A paginated, sortable, filterable list built with the same mechanism as native Dolibarr lists: the icon at the top right of the table lets each user pick their columns, and the preference is stored per user.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:20%;&amp;quot; | Column !! Content&lt;br /&gt;
|-&lt;br /&gt;
| Amount, Fee, Total || The fee popup shows the VAT on the fee whenever a reverse-charge pair or French VAT was posted&lt;br /&gt;
|-&lt;br /&gt;
| Type, Description || Popup with the Stripe ID, the event or source ID, and the full untruncated description&lt;br /&gt;
|-&lt;br /&gt;
| Third party || The customer resolved through the invoice, or through the source charge for its related fee, or the configured Stripe supplier for a subscription fee&lt;br /&gt;
|-&lt;br /&gt;
| Entry || A &amp;quot;Piece no. X&amp;quot; link to the accounting entry, and/or a link to the related bank movement — see the caveat below&lt;br /&gt;
|-&lt;br /&gt;
| Source, Status || The &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; badge opens a popup with the full error message: no need to query the database to understand a failure&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #fc3; background:#fef6e7; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Reading the &amp;quot;Entry&amp;quot; column''' — on a &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt; row, the link points to the '''bank movement''', not to an accounting piece. The module's &amp;lt;code&amp;gt;piece_num&amp;lt;/code&amp;gt; is never the 627/517 entry for the fee: it is only the reverse-charge VAT pair. The fee entry itself is generated later, by Dolibarr's native button, and is never reported back onto this row.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The page is '''purely informational''': no manual posting is offered there. The module posts automatically, and the actual transfer to accounting for fees and payouts happens through the native &amp;quot;Transfer to accounting&amp;quot; button.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; rows ===&lt;br /&gt;
&lt;br /&gt;
Each payment produces '''two rows''' in the database:&lt;br /&gt;
&lt;br /&gt;
* a &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; row, always in status &amp;lt;code&amp;gt;ignored&amp;lt;/code&amp;gt;, fee 0, never processed — present solely for idempotency;&lt;br /&gt;
* a &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; row for the same payment, linked to the first one.&lt;br /&gt;
&lt;br /&gt;
Both appear separately in the list, but the &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; row also carries the link to the payment and the invoice, resolved through a join.&lt;br /&gt;
&lt;br /&gt;
=== Test mode banner ===&lt;br /&gt;
&lt;br /&gt;
While live mode is off, the dashboard, the setup page and the transaction list all display the same warning as the official Stripe module. It is impossible to forget you are working in test mode.&lt;br /&gt;
&lt;br /&gt;
=== Menus ===&lt;br /&gt;
&lt;br /&gt;
Everything sits under '''Banks and cash → Stripe account''' (the official module's menu), flat, as three entries at the same level:&lt;br /&gt;
&lt;br /&gt;
# Stripe dashboard&lt;br /&gt;
# Stripe transactions&lt;br /&gt;
# CSV import ''(administrators only)''&lt;br /&gt;
&lt;br /&gt;
A dashboard link is also added automatically on the bank account record configured as the Stripe account.&lt;br /&gt;
&lt;br /&gt;
== 9. Scheduled job ==&lt;br /&gt;
&lt;br /&gt;
There are two ways to run the sync, both idempotent and safe to re-run. In both cases the code executed is strictly the same: no behavioural difference between the two triggers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #d33; background:#fee7e6; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''⚠ Neither of them starts on its own.'''&lt;br /&gt;
&lt;br /&gt;
Activating the module creates the &amp;lt;code&amp;gt;StripeAccountingSync&amp;lt;/code&amp;gt; job, but '''disabled by default'''. And even once enabled, the Dolibarr scheduler is triggered by nothing until a system crontab calls it. Without both steps, the sync only happens when &amp;quot;Sync now&amp;quot; is clicked manually.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Step 1 — enable the job ===&lt;br /&gt;
&lt;br /&gt;
Under '''Home → Setup → Modules → Scheduled jobs'''. Since &amp;lt;code&amp;gt;llx_cronjob&amp;lt;/code&amp;gt; is a core table, this setting is made through the interface only, never by direct SQL from the module.&lt;br /&gt;
&lt;br /&gt;
=== Step 2 — a system trigger ===&lt;br /&gt;
&lt;br /&gt;
Pick either option.&lt;br /&gt;
&lt;br /&gt;
'''Option A — Dolibarr scheduler''' ''(recommended when several Dolibarr scheduled jobs coexist)''. Runs every due job, not just this one. Requires step 1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
*/15 * * * * curl &amp;quot;https://your-dolibarr/public/cron/cron_run_jobs_by_url.php?securitykey=YOUR_KEY&amp;amp;userlogin=YOUR_LOGIN&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The security key is generated on the scheduled jobs page, &amp;quot;Security of job execution by URL&amp;quot; button.&lt;br /&gt;
&lt;br /&gt;
'''Option B — the module's CLI script.''' Standalone, refuses to run from a browser, and independent of whether the Dolibarr job is enabled.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
*/15 * * * * php /path/to/htdocs/custom/stripeaccounting/cron/stripe_sync.php &amp;gt;&amp;gt; /var/log/stripeaccounting.log 2&amp;gt;&amp;amp;1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 10. Logging and permissions ==&lt;br /&gt;
&lt;br /&gt;
=== Logging ===&lt;br /&gt;
&lt;br /&gt;
Every API call, generated entry, warning or error is traced in &amp;lt;code&amp;gt;llx_stripeaccounting_log&amp;lt;/code&amp;gt;, readable in the database or through the standard Dolibarr log file. Levels: &amp;lt;code&amp;gt;DEBUG&amp;lt;/code&amp;gt; &amp;lt; &amp;lt;code&amp;gt;INFO&amp;lt;/code&amp;gt; &amp;lt; &amp;lt;code&amp;gt;WARNING&amp;lt;/code&amp;gt; &amp;lt; &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;context&amp;lt;/code&amp;gt; column holds the structured detail as JSON (API payload, computed amounts…).&lt;br /&gt;
&lt;br /&gt;
=== Permissions ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Right !! Controls&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;read&amp;lt;/code&amp;gt; || Access to the dashboard and the transaction list&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;write&amp;lt;/code&amp;gt; || Declared for configuration, but not checked in the code today&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;reconcile&amp;lt;/code&amp;gt; || Manual sync triggering&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In practice, &amp;lt;code&amp;gt;admin/setup.php&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;import.php&amp;lt;/code&amp;gt; only check '''Dolibarr administrator''' status, not the &amp;lt;code&amp;gt;write&amp;lt;/code&amp;gt; right: only administrators can configure the module or import a CSV, whatever is ticked in the module permissions.&lt;br /&gt;
&lt;br /&gt;
== 11. Database schema ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;llx_stripeaccounting_transaction&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
One row per processed Stripe object — charge, fee, refund, dispute or payout — all in the same table, distinguished by the &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt; column.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:24%;&amp;quot; | Column !! style=&amp;quot;width:16%;&amp;quot; | Type !! Role&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rowid&amp;lt;/code&amp;gt; || int AI || Primary key&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;entity&amp;lt;/code&amp;gt; || int || Dolibarr multi-company&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_object_id&amp;lt;/code&amp;gt; || varchar(80) || Stripe identifier — '''idempotency anchor'''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_event_id&amp;lt;/code&amp;gt; || varchar(80) || Event identifier, informational only&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt; || varchar(20) || &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;refund&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;dispute&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;other&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_source_id&amp;lt;/code&amp;gt; || varchar(80) || Source Stripe object (e.g. the charge behind a refund)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;source_label&amp;lt;/code&amp;gt; || varchar(80) || Free-text label entered at CSV import; empty for API rows&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;description&amp;lt;/code&amp;gt; || varchar(255) || Stripe label&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;amount&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;net&amp;lt;/code&amp;gt; || decimal(24,8) || Amounts already converted from Stripe cents&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;currency&amp;lt;/code&amp;gt; || varchar(3) || ISO currency code&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;date_created&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;date_available_on&amp;lt;/code&amp;gt; || datetime || Stripe-side dates&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_facture&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fk_paiement&amp;lt;/code&amp;gt; || int || Resolved Dolibarr invoice and payment, if found&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; || int || Generated &amp;lt;code&amp;gt;llx_bank&amp;lt;/code&amp;gt; line ''(empty for a fee in &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; VAT mode)''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;piece_num&amp;lt;/code&amp;gt; || varchar(20) || Generated accounting piece number, where there is one&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt; || varchar(16) || &amp;lt;code&amp;gt;pending&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ignored&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;error_message&amp;lt;/code&amp;gt; || text || Detail on failure&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;date_creation&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;date_processed&amp;lt;/code&amp;gt; || datetime || Technical timestamps&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_user_creat&amp;lt;/code&amp;gt; || int || User who triggered the processing&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Unique key''' on &amp;lt;code&amp;gt;(stripe_object_id, entity)&amp;lt;/code&amp;gt; — this is what guarantees the same Stripe object can never be inserted twice, even with concurrent executions.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;llx_stripeaccounting_log&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Column !! Role&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;level&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;DEBUG&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;INFO&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;WARNING&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;message&amp;lt;/code&amp;gt; || Short message&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;context&amp;lt;/code&amp;gt; || Structured context as JSON&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_stripeaccounting_transaction&amp;lt;/code&amp;gt; || Related transaction, where applicable&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;datec&amp;lt;/code&amp;gt; || Timestamp&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 12. Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:26%;&amp;quot; | Symptom !! Likely cause !! Action&lt;br /&gt;
|-&lt;br /&gt;
| The &amp;quot;Sync now&amp;quot; button is disabled || Minimum configuration incomplete || Fill in the fields listed in the setup page banner&lt;br /&gt;
|-&lt;br /&gt;
| A transaction stays in &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; || Entry rejected by Dolibarr (non-existent account, closed period), or refund not matched || Read &amp;lt;code&amp;gt;error_message&amp;lt;/code&amp;gt; on the row, then the detail in the log table&lt;br /&gt;
|-&lt;br /&gt;
| The Stripe balance is not displayed || API key missing or invalid in the official Stripe module || Check &amp;lt;code&amp;gt;stripe/admin/stripe.php&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| A refund is never reconciled || The original payment was not found through &amp;lt;code&amp;gt;ext_payment_id&amp;lt;/code&amp;gt; || Check that the Stripe payment was recorded by the official module with that identifier&lt;br /&gt;
|-&lt;br /&gt;
| A &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt; stays in &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; || Stripe supplier third party not set, or has no supplier accounting code || Fill the field in setup, and complete the third party record&lt;br /&gt;
|-&lt;br /&gt;
| A CSV-imported refund stays in &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; || '''Normal and expected''' — that account is not linked to &amp;lt;code&amp;gt;ext_payment_id&amp;lt;/code&amp;gt; || Handle the invoice and refund manually in accounting&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 13. Pitfalls encountered ==&lt;br /&gt;
&lt;br /&gt;
Development notes, kept so nobody falls into them again.&lt;br /&gt;
&lt;br /&gt;
* '''&amp;lt;code&amp;gt;PaymentVarious::create()&amp;lt;/code&amp;gt;''' only updates &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; in the database, never on the PHP object. A &amp;lt;code&amp;gt;fetch()&amp;lt;/code&amp;gt; after &amp;lt;code&amp;gt;create()&amp;lt;/code&amp;gt; is required to get the real value.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;select_comptes()&amp;lt;/code&amp;gt;''' prints its own HTML ''and'' returns the number of accounts. Call it as a bare statement: wrapping it in &amp;lt;code&amp;gt;print&amp;lt;/code&amp;gt; would display that number right after the select tag.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;master.inc.php&amp;lt;/code&amp;gt;, not &amp;lt;code&amp;gt;main.inc.php&amp;lt;/code&amp;gt;''' for the CLI script. The latter expects an HTTP session and, in pure CLI, exits silently — no output, no log, return code 0 — inside its redirect to the login page. This gives the misleading impression that the script &amp;quot;does nothing&amp;quot; rather than a real error.&lt;br /&gt;
* '''Core libraries''' — &amp;lt;code&amp;gt;master.inc.php&amp;lt;/code&amp;gt; does not load everything &amp;lt;code&amp;gt;main.inc.php&amp;lt;/code&amp;gt; loads for the web (e.g. &amp;lt;code&amp;gt;core/lib/date.lib.php&amp;lt;/code&amp;gt;, required by &amp;lt;code&amp;gt;BookKeeping&amp;lt;/code&amp;gt;). Include them explicitly if the CLI script evolves.&lt;br /&gt;
* '''The &amp;quot;nothing selected&amp;quot; option is &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;''' in accounting account selectors — see the Configuration section.&lt;br /&gt;
&lt;br /&gt;
== 14. Known limitations ==&lt;br /&gt;
&lt;br /&gt;
* '''Zero-decimal currencies''' (JPY, KRW…) are not handled: amounts are divided by 100 assuming two decimals. Intended use: EUR.&lt;br /&gt;
* '''The 35-day window''' is not configurable. A sync interrupted for longer must be caught up manually.&lt;br /&gt;
* '''Refund matching''' — relies on &amp;lt;code&amp;gt;ext_payment_id&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ext_payment_site&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;llx_paiement&amp;lt;/code&amp;gt;, filled in by the standard Stripe payment flow. A payment recorded any other way cannot be matched automatically. Matching goes through the '''PaymentIntent id''', never the charge id: the core Stripe module never stores the latter ''(it stores either the raw PaymentIntent, or a composite value, depending on the payment path taken)''.&lt;br /&gt;
* '''CSV import assumes French notation''': an export with a decimal point would not be parsed correctly.&lt;br /&gt;
* '''The &amp;quot;Transfer&amp;quot; column of the Payments CSV''' is stored for information only: it is not used to check that the sum of payments matches the imported payout amount.&lt;br /&gt;
* '''CSV-imported refunds always land in &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;''' — intended behaviour, not a bug.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; VAT mode''' — the Stripe account's bank balance does not reflect the fees, see section 5.&lt;br /&gt;
&lt;br /&gt;
[[Category:Dolibarr]]&lt;br /&gt;
[[Category:Modules]]&lt;br /&gt;
[[Category:Accounting]]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Stripeaccounting/en&amp;diff=545</id>
		<title>Stripeaccounting/en</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Stripeaccounting/en&amp;diff=545"/>
				<updated>2026-08-02T12:21:58Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : Page créée avec « {{DISPLAYTITLE:StripeAccounting — Technical documentation}}  &amp;lt;div style=&amp;quot;border:1px solid #c8ccd1; background:#f8f9fa; border-radius:4px; padding:1em 1.2em; margin:0 0 1... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:StripeAccounting — Technical documentation}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border:1px solid #c8ccd1; background:#f8f9fa; border-radius:4px; padding:1em 1.2em; margin:0 0 1.5em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''StripeAccounting''' is a Dolibarr module for '''Stripe accounting reconciliation'''.&lt;br /&gt;
&lt;br /&gt;
It reads the Stripe API (or a CSV export), identifies the movements the official Stripe module does not post — fees, refunds, disputes, payouts — and creates the missing accounting entries.&lt;br /&gt;
&lt;br /&gt;
: '''Compatibility''' — Dolibarr 17+, PHP 7.2 → 8.5&lt;br /&gt;
: '''Depends on''' — Stripe, Bank and Double-entry Accounting modules&lt;br /&gt;
: '''See also''' — [[README|Installation and user guide]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== 1. Design principles ==&lt;br /&gt;
&lt;br /&gt;
Four rules govern the whole module.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:22%;&amp;quot; | Principle !! What it means&lt;br /&gt;
|-&lt;br /&gt;
| '''Complementary''' || The module creates no payment, no invoice, no webhook. It reads Stripe and completes the books, nothing more.&lt;br /&gt;
|-&lt;br /&gt;
| '''Idempotent''' || Each Stripe object is processed once only, no matter how many times the sync is re-run.&lt;br /&gt;
|-&lt;br /&gt;
| '''Never guess''' || If an operation cannot be matched with certainty, nothing is posted: the row goes to &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; for manual review.&lt;br /&gt;
|-&lt;br /&gt;
| '''Configuration is blocking''' || As long as the minimum configuration is incomplete, no sync runs at all (no button, no cron, no import).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2. Requirements ==&lt;br /&gt;
&lt;br /&gt;
=== Required Dolibarr modules ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Module !! What it provides&lt;br /&gt;
|-&lt;br /&gt;
| '''Stripe''' (&amp;lt;code&amp;gt;modStripe&amp;lt;/code&amp;gt;) || API key, test/live mode, Stripe financial account&lt;br /&gt;
|-&lt;br /&gt;
| '''Bank''' (&amp;lt;code&amp;gt;modBanque&amp;lt;/code&amp;gt;) || &amp;lt;code&amp;gt;llx_bank&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;llx_bank_account&amp;lt;/code&amp;gt; tables&lt;br /&gt;
|-&lt;br /&gt;
| '''Double-entry accounting''' (&amp;lt;code&amp;gt;modAccounting&amp;lt;/code&amp;gt;) || &amp;lt;code&amp;gt;llx_accounting_bookkeeping&amp;lt;/code&amp;gt; table&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Mandatory Dolibarr setting ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ACCOUNTING_ACCOUNT_TRANSFER_CASH&amp;lt;/code&amp;gt; must be set under '''Accounting → Setup → Miscellaneous accounts'''. Without it, the internal transfer generated by payouts cannot be transferred to accounting (a Dolibarr limitation, not a module one).&lt;br /&gt;
&lt;br /&gt;
=== Notes ===&lt;br /&gt;
&lt;br /&gt;
* The Stripe PHP SDK is not re-vendored: the module reuses the core copy (&amp;lt;code&amp;gt;includes/stripe/stripe-php/&amp;lt;/code&amp;gt;).&lt;br /&gt;
* The code deliberately avoids any PHP syntax newer than 7.2 (no &amp;lt;code&amp;gt;match&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;?-&amp;gt;&amp;lt;/code&amp;gt;, enums, typed properties, &amp;lt;code&amp;gt;str_contains&amp;lt;/code&amp;gt;…) so it runs across the whole 7.2 → 8.5 range.&lt;br /&gt;
&lt;br /&gt;
== 3. File tree ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
custom/stripeaccounting/&lt;br /&gt;
├── core/modules/modStripeAccounting.class.php   Module descriptor (permissions, menus, cron, constants)&lt;br /&gt;
├── class/&lt;br /&gt;
│   ├── StripeApi.class.php                      Stripe SDK wrapper (read-only)&lt;br /&gt;
│   ├── StripeRepository.class.php               SQL access + idempotency&lt;br /&gt;
│   ├── StripeLogger.class.php                   Logging&lt;br /&gt;
│   ├── StripeAccounting.class.php               Accounting entry generation&lt;br /&gt;
│   ├── StripePayout.class.php                   Payout reconciliation&lt;br /&gt;
│   ├── StripeSync.class.php                     Orchestrator (cron entry point)&lt;br /&gt;
│   ├── StripeCsvImporter.class.php              CSV import&lt;br /&gt;
│   └── actions_stripeaccounting.class.php       'bankcard' hook&lt;br /&gt;
├── admin/setup.php                              Configuration&lt;br /&gt;
├── import.php                                   CSV import&lt;br /&gt;
├── dashboard.php                                Dashboard&lt;br /&gt;
├── transaction_list.php                         Transaction list&lt;br /&gt;
├── cron/stripe_sync.php                         CLI entry point&lt;br /&gt;
├── lib/stripeaccounting.lib.php&lt;br /&gt;
├── sql/&lt;br /&gt;
├── langs/{fr_FR,en_US,es_ES,it_IT,de_DE}/&lt;br /&gt;
└── css/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dependency direction ===&lt;br /&gt;
&lt;br /&gt;
: pages and hook → &amp;lt;code&amp;gt;StripeSync&amp;lt;/code&amp;gt; → (&amp;lt;code&amp;gt;StripeApi&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StripeRepository&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StripeAccounting&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StripePayout&amp;lt;/code&amp;gt;) → &amp;lt;code&amp;gt;StripeLogger&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:26%;&amp;quot; | Class !! Role&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeApi&amp;lt;/code&amp;gt; || Queries the Stripe SDK (balance transactions, charges, refunds, disputes, payouts) with automatic pagination. No database access, no accounting entries.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeRepository&amp;lt;/code&amp;gt; || All SQL for the module's two tables. &amp;lt;code&amp;gt;upsertTransaction()&amp;lt;/code&amp;gt; is the idempotency anchor.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeLogger&amp;lt;/code&amp;gt; || Writes to &amp;lt;code&amp;gt;llx_stripeaccounting_log&amp;lt;/code&amp;gt; and mirrors to &amp;lt;code&amp;gt;dol_syslog()&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeAccounting&amp;lt;/code&amp;gt; || Builds accounting entries (refund, dispute, reverse-charge VAT) or bank movements (fees). Exposes &amp;lt;code&amp;gt;checkConfig()&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripePayout&amp;lt;/code&amp;gt; || Creates the internal bank transfer between the Stripe account and the real bank account.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeSync&amp;lt;/code&amp;gt; || Orchestrator: one method per flow, plus &amp;lt;code&amp;gt;reconcileStripeAccount()&amp;lt;/code&amp;gt; which chains them all.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeCsvImporter&amp;lt;/code&amp;gt; || Feeds the same pipeline from a Stripe CSV export.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ActionsStripeAccounting&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;bankcard&amp;lt;/code&amp;gt; hook: dashboard link on the Stripe account record.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 4. Synchronisation and idempotency ==&lt;br /&gt;
&lt;br /&gt;
Every flow (&amp;lt;code&amp;gt;syncFees&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncRefunds&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncDisputes&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncPayouts&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncTransactions&amp;lt;/code&amp;gt;) always follows the same steps:&lt;br /&gt;
&lt;br /&gt;
# '''Check the configuration''' — if incomplete: &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt; log, immediate stop, no API call at all.&lt;br /&gt;
# '''List Stripe objects''' over a rolling window of '''35 days'''.&lt;br /&gt;
# '''Filter''' — an object is skipped only if it already exists ''and'' its status is &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;ignored&amp;lt;/code&amp;gt;. A row in &amp;lt;code&amp;gt;pending&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; is '''retried''' on this run.&lt;br /&gt;
# '''Record''' it as &amp;lt;code&amp;gt;pending&amp;lt;/code&amp;gt;, then generate the accounting entry or bank movement.&lt;br /&gt;
# '''Conclude''' — success: status &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt;. Failure: status &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; with the message, and '''the batch carries on''' with the next object.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #36c; background:#eaf3ff; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Automatic retry''' — a row in &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; becomes eligible again on the next run. Once the cause is fixed (a fiscal year created late, for instance), no manual action is needed.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Why duplicates are impossible ===&lt;br /&gt;
&lt;br /&gt;
* '''Unique database key''' on &amp;lt;code&amp;gt;(stripe_object_id, entity)&amp;lt;/code&amp;gt; — protects even against two concurrent cron executions.&lt;br /&gt;
* '''Explicit check before processing''' — avoids even attempting to post an entry for an already-finalised object.&lt;br /&gt;
&lt;br /&gt;
=== Special cases: &amp;lt;code&amp;gt;adjustment&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;payment_failure_refund&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
These are balance corrections Stripe makes on its own (reversal after a dispute is resolved, automatic refund of a payment that ultimately failed). The module '''records''' them — otherwise they would stay invisible — but '''never''' posts them automatically: the sign of the amount and the underlying cause vary too much. They are created directly in &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, with an explicit message, to be handled manually.&lt;br /&gt;
&lt;br /&gt;
== 5. Accounting entries ==&lt;br /&gt;
&lt;br /&gt;
All lines of a single Stripe event share the same &amp;lt;code&amp;gt;doc_type='stripeaccounting'&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fk_doc&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;doc_ref&amp;lt;/code&amp;gt; triplet: Dolibarr automatically groups them under one piece number, so the module needs no numbering scheme of its own.&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! Event !! What the module does !! Resulting entry&lt;br /&gt;
|-&lt;br /&gt;
| Stripe fee ''(VAT mode &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt;)'' || &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; bank movement || 627xxx / 517xxx entry generated later by Dolibarr&lt;br /&gt;
|-&lt;br /&gt;
| Stripe fee ''(&amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt; mode)'' || Plus: VAT pair posted immediately || Debit deductible VAT, credit reverse-charge VAT ''(net impact nil)''&lt;br /&gt;
|-&lt;br /&gt;
| Stripe fee ''(&amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; mode)'' || Full direct entry || Debit fee account excl. VAT + deductible VAT, credit Stripe account incl. VAT&lt;br /&gt;
|-&lt;br /&gt;
| Subscription / service fees ''(Radar, Billing, Connect…)'' || &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; bank movement || Entry generated later by Dolibarr, on the Stripe supplier account&lt;br /&gt;
|-&lt;br /&gt;
| Payout || Internal bank transfer between the two accounts || Entry generated later by Dolibarr&lt;br /&gt;
|-&lt;br /&gt;
| Refund ''(invoice found)'' || Direct entry || Debit customer account 411xxx, credit Stripe account 517xxx&lt;br /&gt;
|-&lt;br /&gt;
| Refund ''(invoice not found)'' || Nothing || Status &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, handle manually&lt;br /&gt;
|-&lt;br /&gt;
| Dispute / chargeback || Direct entry || Debit dispute loss 658xxx, credit Stripe account 517xxx ''(+ fee account if fees apply)''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Why fees and payouts produce no direct entry ===&lt;br /&gt;
&lt;br /&gt;
The historical problem: when a Stripe-paid invoice is transferred to accounting through Dolibarr's standard workflow, the payment is posted at its '''gross''' amount — fees are ignored at that stage.&lt;br /&gt;
&lt;br /&gt;
If the module posted its own entry ''and'' its own bank line on top of that, this line would stay invisible to &amp;lt;code&amp;gt;bankjournal.php&amp;lt;/code&amp;gt; — which only recognises lines attached to &amp;lt;code&amp;gt;doc_type='bank'&amp;lt;/code&amp;gt;. An administrator transferring the bank account to accounting &amp;quot;normally&amp;quot; would then create a '''second''' entry for the very same movement.&lt;br /&gt;
&lt;br /&gt;
'''The chosen solution:''' for fees, subscription fees and payouts, the module now creates only the '''real bank movement''', using Dolibarr's native mechanisms. The native ''&amp;quot;Transfer to accounting&amp;quot;'' button then produces the entry, exactly as for any other bank movement. In those three cases, the module no longer touches &amp;lt;code&amp;gt;llx_accounting_bookkeeping&amp;lt;/code&amp;gt; at all.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:22%;&amp;quot; | Case !! Native mechanism used&lt;br /&gt;
|-&lt;br /&gt;
| Fees and subscription fees || &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; (bank movement with an explicit counterpart account, no third party or invoice), carrying its own &amp;lt;code&amp;gt;accountancy_code&amp;lt;/code&amp;gt;, which &amp;lt;code&amp;gt;bankjournal.php&amp;lt;/code&amp;gt; reads directly.&lt;br /&gt;
|-&lt;br /&gt;
| Payouts || Dolibarr internal transfer: &amp;lt;code&amp;gt;Account::addline()&amp;lt;/code&amp;gt; on both sides, plus &amp;lt;code&amp;gt;add_url_line(…, 'banktransfert')&amp;lt;/code&amp;gt;. The counterpart is posted to &amp;lt;code&amp;gt;ACCOUNTING_ACCOUNT_TRANSFER_CASH&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In both cases the status becomes &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt; — the module's job is done — but '''&amp;lt;code&amp;gt;piece_num&amp;lt;/code&amp;gt; stays empty''': the entry does not exist yet, only &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; is set. After the manual transfer, it can be found with &amp;lt;code&amp;gt;doc_type='bank'&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;fk_doc&amp;lt;/code&amp;gt; equal to the row's &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #fc3; background:#fef6e7; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Worth knowing''' — the payout entry only balances to zero on the transfer account once '''both''' bank accounts (Stripe ''and'' the real bank) have been transferred to accounting, not just one of them.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #d33; background:#fee7e6; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''⚠ &amp;lt;code&amp;gt;STRIPE_AUTO_RECORD_PAYOUT&amp;lt;/code&amp;gt; must stay disabled'''&lt;br /&gt;
&lt;br /&gt;
Once this module handles payouts, untick &amp;quot;Enable automatic recording of Stripe payments&amp;quot; in &amp;lt;code&amp;gt;stripe/admin/stripe.php&amp;lt;/code&amp;gt; — despite its wording, that checkbox only concerns payouts.&lt;br /&gt;
&lt;br /&gt;
Otherwise the official module's webhook and this module would each create their own bank movement for the same payout, unaware of each other.&lt;br /&gt;
&lt;br /&gt;
The core webhook keeps '''no''' trace of the payout id it has processed: should Stripe deliver the event twice (delivery is guaranteed &amp;quot;at least once&amp;quot;), nothing stops it from duplicating on its own either. This module has real idempotency and automatically catches up any missed payout within 35 days.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The &amp;quot;Stripe transfers&amp;quot; page is hidden ===&lt;br /&gt;
&lt;br /&gt;
On activation, &amp;lt;code&amp;gt;modStripeAccounting::init()&amp;lt;/code&amp;gt; disables the &amp;lt;code&amp;gt;stripe/payout.php&amp;lt;/code&amp;gt; menu entry: that page queries the API live without recording anything, and having it alongside this module would only create confusion about which one is authoritative for payouts. &amp;lt;code&amp;gt;remove()&amp;lt;/code&amp;gt; restores the original condition. '''This is the only core table the module modifies''' — deliberate, and documented here for that reason.&lt;br /&gt;
&lt;br /&gt;
=== Per-transaction fees or subscription fees? ===&lt;br /&gt;
&lt;br /&gt;
Stripe bills two distinct things under the generic word &amp;quot;fees&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! !! Per-transaction fees !! Subscription / service fees&lt;br /&gt;
|-&lt;br /&gt;
! Example&lt;br /&gt;
| Commission on each payment || Radar, Billing, Connect&lt;br /&gt;
|-&lt;br /&gt;
! Where to find it&lt;br /&gt;
| The &amp;lt;code&amp;gt;.fee&amp;lt;/code&amp;gt; field of a &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; balance transaction || A dedicated balance transaction, type &amp;lt;code&amp;gt;stripe_fee&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;application_fee&amp;lt;/code&amp;gt; ''(its &amp;lt;code&amp;gt;.fee&amp;lt;/code&amp;gt; is always 0, the amount sits in &amp;lt;code&amp;gt;.amount&amp;lt;/code&amp;gt;)''&lt;br /&gt;
|-&lt;br /&gt;
! Account used&lt;br /&gt;
| The configured fee account (627xxx) || The supplier accounting code of the configured Stripe third party&lt;br /&gt;
|-&lt;br /&gt;
! Type in database&lt;br /&gt;
| &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Limitation of the &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; VAT mode ===&lt;br /&gt;
&lt;br /&gt;
This mode has to split the gross amount into net + VAT, something &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; cannot express. It therefore keeps the previous behaviour: a full direct entry, with no bank movement created. No duplicate risk (precisely because no bank line is produced), but the &amp;lt;code&amp;gt;llx_bank&amp;lt;/code&amp;gt; balance of the Stripe account will never reflect the fees while this mode is active.&lt;br /&gt;
&lt;br /&gt;
== 6. CSV import ==&lt;br /&gt;
&lt;br /&gt;
The import covers the case of a Stripe account '''different''' from the one configured in the official module — another PrestaShop shop with its own merchant account, for example. The API has no access to it: its contents are exported to CSV from the Stripe dashboard, then imported.&lt;br /&gt;
&lt;br /&gt;
=== Starting assumption ===&lt;br /&gt;
&lt;br /&gt;
The invoices and payments of that shop are '''already''' posted in Dolibarr through some other process, and the collection (debit 517, credit 411) is already booked. Only the '''fees''', '''refunds''' and '''payouts''' are missing — which is exactly what the import handles.&lt;br /&gt;
&lt;br /&gt;
=== Interface: a single field ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;import.php&amp;lt;/code&amp;gt; now exposes only one upload field, '''General history''', wired to &amp;lt;code&amp;gt;importGeneralHistory()&amp;lt;/code&amp;gt;. That file alone covers every movement type.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;importPayments()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;importPayouts()&amp;lt;/code&amp;gt; are still implemented and functional, but no longer reachable from the interface; they are documented below for reference.&lt;br /&gt;
&lt;br /&gt;
Like the &amp;quot;Sync now&amp;quot; button, the import is blocked — warning banner, disabled button, server-side guard — while the configuration is incomplete.&lt;br /&gt;
&lt;br /&gt;
=== The three methods ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:24%;&amp;quot; | Method !! Stripe export read !! Processing&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;importGeneralHistory()&amp;lt;/code&amp;gt;&amp;lt;br /&amp;gt;''(the only one exposed)'' || Balance history || Dispatch on the &amp;lt;code&amp;gt;Type&amp;lt;/code&amp;gt; column, see table below&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;importPayments()&amp;lt;/code&amp;gt; || Payments || Fee → fee movement. Amount refunded → &amp;lt;code&amp;gt;refund&amp;lt;/code&amp;gt; row, always in &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;importPayouts()&amp;lt;/code&amp;gt; || Payouts || Exactly the same processing as a payout coming from the API&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
General history dispatch, by &amp;lt;code&amp;gt;Type&amp;lt;/code&amp;gt; column:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:30%;&amp;quot; | Stripe type !! Processing&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt; || Internal bank transfer, as via the API&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;payment&amp;lt;/code&amp;gt; with a fee || Fee movement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_fee&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;application_fee&amp;lt;/code&amp;gt; || Subscription fee, on the Stripe supplier account&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;refund&amp;lt;/code&amp;gt; || Recorded, '''always''' in &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;payout_minimum_balance_hold&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;…_release&amp;lt;/code&amp;gt; || '''Ignored''' — Stripe rolling reserve, no real cash movement, nothing to post&lt;br /&gt;
|-&lt;br /&gt;
| any other type || Recorded as &amp;lt;code&amp;gt;type='other'&amp;lt;/code&amp;gt;, status &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, raw Stripe type kept in the description. No guessed entry.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Columns are matched '''by name''': their order does not matter, and extra unused columns are ignored.&lt;br /&gt;
&lt;br /&gt;
=== Import idempotency ===&lt;br /&gt;
&lt;br /&gt;
The unique key protects against any double import: re-importing the same CSV, or one overlapping a previous import, creates no duplicate.&lt;br /&gt;
&lt;br /&gt;
An important detail: in the general history, &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;payment&amp;lt;/code&amp;gt; rows are indexed by their '''&amp;lt;code&amp;gt;Source&amp;lt;/code&amp;gt;''' column (&amp;lt;code&amp;gt;po_…&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ch_…&amp;lt;/code&amp;gt;), not by the row's own &amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;txn_…&amp;lt;/code&amp;gt;) — the very same key the dedicated imports use. Importing the general history '''on top of''' the specific exports therefore never posts the same entry twice, in any order.&lt;br /&gt;
&lt;br /&gt;
Since Stripe identifiers are unique platform-wide, mixing rows from the API account and from several CSV-imported accounts in the same table carries no collision risk.&lt;br /&gt;
&lt;br /&gt;
=== Practical details ===&lt;br /&gt;
&lt;br /&gt;
* '''Source label''' — a free-text field entered at import time (e.g. &amp;quot;DRM shop&amp;quot;) is stored on every created row and serves as a column and filter in the list, to tell several shops apart side by side.&lt;br /&gt;
* '''Amount format''' — Stripe CSVs use the French decimal comma, converted through &amp;lt;code&amp;gt;price2num()&amp;lt;/code&amp;gt;. Dates marked &amp;lt;code&amp;gt;(UTC)&amp;lt;/code&amp;gt; are interpreted as such.&lt;br /&gt;
&lt;br /&gt;
== 7. Configuration ==&lt;br /&gt;
&lt;br /&gt;
The API key and test/live mode are '''not''' re-entered here: they are read, read-only, from the official Stripe module.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:26%;&amp;quot; | Field !! Constant !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| Stripe financial account || &amp;lt;code&amp;gt;STRIPE_BANK_ACCOUNT_FOR_PAYMENTS&amp;lt;/code&amp;gt; ''(official module constant)'' || Bank account selector. No local copy, hence no risk of divergence.&lt;br /&gt;
|-&lt;br /&gt;
| Main bank account || &amp;lt;code&amp;gt;STRIPE_BANK_ACCOUNT_FOR_BANKTRANSFERS&amp;lt;/code&amp;gt; ''(official module constant)'' || Same selector. See the box below.&lt;br /&gt;
|-&lt;br /&gt;
| Fee account || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_FRAIS&amp;lt;/code&amp;gt; || Account number, e.g. 627xxx&lt;br /&gt;
|-&lt;br /&gt;
| Dispute account || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_LITIGES&amp;lt;/code&amp;gt; || Account number, e.g. 658xxx. '''Required''' — used as soon as a dispute occurs, whatever the VAT mode.&lt;br /&gt;
|-&lt;br /&gt;
| Stripe supplier third party || &amp;lt;code&amp;gt;STRIPEACCOUNTING_FOURNISSEUR_STRIPE_ID&amp;lt;/code&amp;gt; || A third party flagged as supplier; its supplier accounting code is what gets used. Optional, unless subscription fees exist.&lt;br /&gt;
|-&lt;br /&gt;
| VAT mode || &amp;lt;code&amp;gt;STRIPEACCOUNTING_VAT_MODE&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Deductible VAT account (intra-EU) || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_TVA_DEDUCTIBLE&amp;lt;/code&amp;gt; || Required when the VAT mode is not &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt;. Stripe always invoices from a non-French EU entity, so the deductible VAT is intra-EU in every case.&lt;br /&gt;
|-&lt;br /&gt;
| VAT due account (intra-EU) || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_TVA_AUTOLIQUIDATION&amp;lt;/code&amp;gt; || Required in &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt; mode only — never used in &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; mode.&lt;br /&gt;
|-&lt;br /&gt;
| VAT rate || &amp;lt;code&amp;gt;STRIPEACCOUNTING_VAT_RATE&amp;lt;/code&amp;gt; || Percentage, 20 by default&lt;br /&gt;
|-&lt;br /&gt;
| Sync frequency || &amp;lt;code&amp;gt;STRIPEACCOUNTING_SYNC_UNITFREQUENCY&amp;lt;/code&amp;gt; || Applied to the scheduled job (in seconds)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #36c; background:#eaf3ff; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Why redefine the main bank account here?'''&lt;br /&gt;
&lt;br /&gt;
The official Stripe module's setup page only renders that field when &amp;lt;code&amp;gt;STRIPE_AUTO_RECORD_PAYOUT&amp;lt;/code&amp;gt; is enabled — and its own save handler resets the value to 0 on every save while the field is not rendered. Yet that setting must stay disabled once this module handles payouts. The field is therefore re-exposed here, writing the core constant directly, so the value stays configurable and stable.&lt;br /&gt;
&lt;br /&gt;
Both account selectors only write their constant when a real account was submitted: saving the page for some unrelated field never overwrites a correct value.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Configuration check ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;StripeAccounting::checkConfig()&amp;lt;/code&amp;gt; returns the list of missing constants. It is called both by the setup page (information banner) and by every sync entry point (the real guard that blocks all processing).&lt;br /&gt;
&lt;br /&gt;
=== Pitfall with accounting account selectors ===&lt;br /&gt;
&lt;br /&gt;
The four fields using &amp;lt;code&amp;gt;FormAccounting::select_account()&amp;lt;/code&amp;gt; (fees, disputes, both VAT accounts) have a &amp;quot;nothing selected&amp;quot; option whose value is '''&amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;''' — a non-empty string, therefore truthy in PHP. A field left blank and saved literally stores &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;StripeAccounting::getAccountConst()&amp;lt;/code&amp;gt; normalises that value to an empty string on read, everywhere these constants are read. No entry can therefore land on the non-existent account &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 8. User interface ==&lt;br /&gt;
&lt;br /&gt;
=== Dashboard ===&lt;br /&gt;
&lt;br /&gt;
Stripe balance (live API call), number of unreconciled transactions, total fees for the month, pending payouts, and a '''Sync now''' button — disabled, with a banner listing the missing constants, while the configuration is incomplete.&lt;br /&gt;
&lt;br /&gt;
=== Transaction list ===&lt;br /&gt;
&lt;br /&gt;
A paginated, sortable, filterable list built with the same mechanism as native Dolibarr lists: the icon at the top right of the table lets each user pick their columns, and the preference is stored per user.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:20%;&amp;quot; | Column !! Content&lt;br /&gt;
|-&lt;br /&gt;
| Amount, Fee, Total || The fee popup shows the VAT on the fee whenever a reverse-charge pair or French VAT was posted&lt;br /&gt;
|-&lt;br /&gt;
| Type, Description || Popup with the Stripe ID, the event or source ID, and the full untruncated description&lt;br /&gt;
|-&lt;br /&gt;
| Third party || The customer resolved through the invoice, or through the source charge for its related fee, or the configured Stripe supplier for a subscription fee&lt;br /&gt;
|-&lt;br /&gt;
| Entry || A &amp;quot;Piece no. X&amp;quot; link to the accounting entry, and/or a link to the related bank movement — see the caveat below&lt;br /&gt;
|-&lt;br /&gt;
| Source, Status || The &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; badge opens a popup with the full error message: no need to query the database to understand a failure&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #fc3; background:#fef6e7; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Reading the &amp;quot;Entry&amp;quot; column''' — on a &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt; row, the link points to the '''bank movement''', not to an accounting piece. The module's &amp;lt;code&amp;gt;piece_num&amp;lt;/code&amp;gt; is never the 627/517 entry for the fee: it is only the reverse-charge VAT pair. The fee entry itself is generated later, by Dolibarr's native button, and is never reported back onto this row.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The page is '''purely informational''': no manual posting is offered there. The module posts automatically, and the actual transfer to accounting for fees and payouts happens through the native &amp;quot;Transfer to accounting&amp;quot; button.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; rows ===&lt;br /&gt;
&lt;br /&gt;
Each payment produces '''two rows''' in the database:&lt;br /&gt;
&lt;br /&gt;
* a &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; row, always in status &amp;lt;code&amp;gt;ignored&amp;lt;/code&amp;gt;, fee 0, never processed — present solely for idempotency;&lt;br /&gt;
* a &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; row for the same payment, linked to the first one.&lt;br /&gt;
&lt;br /&gt;
Both appear separately in the list, but the &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; row also carries the link to the payment and the invoice, resolved through a join.&lt;br /&gt;
&lt;br /&gt;
=== Test mode banner ===&lt;br /&gt;
&lt;br /&gt;
While live mode is off, the dashboard, the setup page and the transaction list all display the same warning as the official Stripe module. It is impossible to forget you are working in test mode.&lt;br /&gt;
&lt;br /&gt;
=== Menus ===&lt;br /&gt;
&lt;br /&gt;
Everything sits under '''Banks and cash → Stripe account''' (the official module's menu), flat, as three entries at the same level:&lt;br /&gt;
&lt;br /&gt;
# Stripe dashboard&lt;br /&gt;
# Stripe transactions&lt;br /&gt;
# CSV import ''(administrators only)''&lt;br /&gt;
&lt;br /&gt;
A dashboard link is also added automatically on the bank account record configured as the Stripe account.&lt;br /&gt;
&lt;br /&gt;
== 9. Scheduled job ==&lt;br /&gt;
&lt;br /&gt;
There are two ways to run the sync, both idempotent and safe to re-run. In both cases the code executed is strictly the same: no behavioural difference between the two triggers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #d33; background:#fee7e6; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''⚠ Neither of them starts on its own.'''&lt;br /&gt;
&lt;br /&gt;
Activating the module creates the &amp;lt;code&amp;gt;StripeAccountingSync&amp;lt;/code&amp;gt; job, but '''disabled by default'''. And even once enabled, the Dolibarr scheduler is triggered by nothing until a system crontab calls it. Without both steps, the sync only happens when &amp;quot;Sync now&amp;quot; is clicked manually.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Step 1 — enable the job ===&lt;br /&gt;
&lt;br /&gt;
Under '''Home → Setup → Modules → Scheduled jobs'''. Since &amp;lt;code&amp;gt;llx_cronjob&amp;lt;/code&amp;gt; is a core table, this setting is made through the interface only, never by direct SQL from the module.&lt;br /&gt;
&lt;br /&gt;
=== Step 2 — a system trigger ===&lt;br /&gt;
&lt;br /&gt;
Pick either option.&lt;br /&gt;
&lt;br /&gt;
'''Option A — Dolibarr scheduler''' ''(recommended when several Dolibarr scheduled jobs coexist)''. Runs every due job, not just this one. Requires step 1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
*/15 * * * * curl &amp;quot;https://your-dolibarr/public/cron/cron_run_jobs_by_url.php?securitykey=YOUR_KEY&amp;amp;userlogin=YOUR_LOGIN&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The security key is generated on the scheduled jobs page, &amp;quot;Security of job execution by URL&amp;quot; button.&lt;br /&gt;
&lt;br /&gt;
'''Option B — the module's CLI script.''' Standalone, refuses to run from a browser, and independent of whether the Dolibarr job is enabled.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
*/15 * * * * php /path/to/htdocs/custom/stripeaccounting/cron/stripe_sync.php &amp;gt;&amp;gt; /var/log/stripeaccounting.log 2&amp;gt;&amp;amp;1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 10. Logging and permissions ==&lt;br /&gt;
&lt;br /&gt;
=== Logging ===&lt;br /&gt;
&lt;br /&gt;
Every API call, generated entry, warning or error is traced in &amp;lt;code&amp;gt;llx_stripeaccounting_log&amp;lt;/code&amp;gt;, readable in the database or through the standard Dolibarr log file. Levels: &amp;lt;code&amp;gt;DEBUG&amp;lt;/code&amp;gt; &amp;lt; &amp;lt;code&amp;gt;INFO&amp;lt;/code&amp;gt; &amp;lt; &amp;lt;code&amp;gt;WARNING&amp;lt;/code&amp;gt; &amp;lt; &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;context&amp;lt;/code&amp;gt; column holds the structured detail as JSON (API payload, computed amounts…).&lt;br /&gt;
&lt;br /&gt;
=== Permissions ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Right !! Controls&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;read&amp;lt;/code&amp;gt; || Access to the dashboard and the transaction list&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;write&amp;lt;/code&amp;gt; || Declared for configuration, but not checked in the code today&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;reconcile&amp;lt;/code&amp;gt; || Manual sync triggering&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In practice, &amp;lt;code&amp;gt;admin/setup.php&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;import.php&amp;lt;/code&amp;gt; only check '''Dolibarr administrator''' status, not the &amp;lt;code&amp;gt;write&amp;lt;/code&amp;gt; right: only administrators can configure the module or import a CSV, whatever is ticked in the module permissions.&lt;br /&gt;
&lt;br /&gt;
== 11. Database schema ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;llx_stripeaccounting_transaction&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
One row per processed Stripe object — charge, fee, refund, dispute or payout — all in the same table, distinguished by the &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt; column.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:24%;&amp;quot; | Column !! style=&amp;quot;width:16%;&amp;quot; | Type !! Role&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rowid&amp;lt;/code&amp;gt; || int AI || Primary key&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;entity&amp;lt;/code&amp;gt; || int || Dolibarr multi-company&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_object_id&amp;lt;/code&amp;gt; || varchar(80) || Stripe identifier — '''idempotency anchor'''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_event_id&amp;lt;/code&amp;gt; || varchar(80) || Event identifier, informational only&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt; || varchar(20) || &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;refund&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;dispute&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;other&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_source_id&amp;lt;/code&amp;gt; || varchar(80) || Source Stripe object (e.g. the charge behind a refund)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;source_label&amp;lt;/code&amp;gt; || varchar(80) || Free-text label entered at CSV import; empty for API rows&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;description&amp;lt;/code&amp;gt; || varchar(255) || Stripe label&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;amount&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;net&amp;lt;/code&amp;gt; || decimal(24,8) || Amounts already converted from Stripe cents&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;currency&amp;lt;/code&amp;gt; || varchar(3) || ISO currency code&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;date_created&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;date_available_on&amp;lt;/code&amp;gt; || datetime || Stripe-side dates&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_facture&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fk_paiement&amp;lt;/code&amp;gt; || int || Resolved Dolibarr invoice and payment, if found&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; || int || Generated &amp;lt;code&amp;gt;llx_bank&amp;lt;/code&amp;gt; line ''(empty for a fee in &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; VAT mode)''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;piece_num&amp;lt;/code&amp;gt; || varchar(20) || Generated accounting piece number, where there is one&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt; || varchar(16) || &amp;lt;code&amp;gt;pending&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ignored&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;error_message&amp;lt;/code&amp;gt; || text || Detail on failure&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;date_creation&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;date_processed&amp;lt;/code&amp;gt; || datetime || Technical timestamps&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_user_creat&amp;lt;/code&amp;gt; || int || User who triggered the processing&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Unique key''' on &amp;lt;code&amp;gt;(stripe_object_id, entity)&amp;lt;/code&amp;gt; — this is what guarantees the same Stripe object can never be inserted twice, even with concurrent executions.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;llx_stripeaccounting_log&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Column !! Role&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;level&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;DEBUG&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;INFO&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;WARNING&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;message&amp;lt;/code&amp;gt; || Short message&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;context&amp;lt;/code&amp;gt; || Structured context as JSON&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_stripeaccounting_transaction&amp;lt;/code&amp;gt; || Related transaction, where applicable&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;datec&amp;lt;/code&amp;gt; || Timestamp&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 12. Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:26%;&amp;quot; | Symptom !! Likely cause !! Action&lt;br /&gt;
|-&lt;br /&gt;
| The &amp;quot;Sync now&amp;quot; button is disabled || Minimum configuration incomplete || Fill in the fields listed in the setup page banner&lt;br /&gt;
|-&lt;br /&gt;
| A transaction stays in &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; || Entry rejected by Dolibarr (non-existent account, closed period), or refund not matched || Read &amp;lt;code&amp;gt;error_message&amp;lt;/code&amp;gt; on the row, then the detail in the log table&lt;br /&gt;
|-&lt;br /&gt;
| The Stripe balance is not displayed || API key missing or invalid in the official Stripe module || Check &amp;lt;code&amp;gt;stripe/admin/stripe.php&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| A refund is never reconciled || The original payment was not found through &amp;lt;code&amp;gt;ext_payment_id&amp;lt;/code&amp;gt; || Check that the Stripe payment was recorded by the official module with that identifier&lt;br /&gt;
|-&lt;br /&gt;
| A &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt; stays in &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; || Stripe supplier third party not set, or has no supplier accounting code || Fill the field in setup, and complete the third party record&lt;br /&gt;
|-&lt;br /&gt;
| A CSV-imported refund stays in &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; || '''Normal and expected''' — that account is not linked to &amp;lt;code&amp;gt;ext_payment_id&amp;lt;/code&amp;gt; || Handle the invoice and refund manually in accounting&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 13. Pitfalls encountered ==&lt;br /&gt;
&lt;br /&gt;
Development notes, kept so nobody falls into them again.&lt;br /&gt;
&lt;br /&gt;
* '''&amp;lt;code&amp;gt;PaymentVarious::create()&amp;lt;/code&amp;gt;''' only updates &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; in the database, never on the PHP object. A &amp;lt;code&amp;gt;fetch()&amp;lt;/code&amp;gt; after &amp;lt;code&amp;gt;create()&amp;lt;/code&amp;gt; is required to get the real value.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;select_comptes()&amp;lt;/code&amp;gt;''' prints its own HTML ''and'' returns the number of accounts. Call it as a bare statement: wrapping it in &amp;lt;code&amp;gt;print&amp;lt;/code&amp;gt; would display that number right after the select tag.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;master.inc.php&amp;lt;/code&amp;gt;, not &amp;lt;code&amp;gt;main.inc.php&amp;lt;/code&amp;gt;''' for the CLI script. The latter expects an HTTP session and, in pure CLI, exits silently — no output, no log, return code 0 — inside its redirect to the login page. This gives the misleading impression that the script &amp;quot;does nothing&amp;quot; rather than a real error.&lt;br /&gt;
* '''Core libraries''' — &amp;lt;code&amp;gt;master.inc.php&amp;lt;/code&amp;gt; does not load everything &amp;lt;code&amp;gt;main.inc.php&amp;lt;/code&amp;gt; loads for the web (e.g. &amp;lt;code&amp;gt;core/lib/date.lib.php&amp;lt;/code&amp;gt;, required by &amp;lt;code&amp;gt;BookKeeping&amp;lt;/code&amp;gt;). Include them explicitly if the CLI script evolves.&lt;br /&gt;
* '''The &amp;quot;nothing selected&amp;quot; option is &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;''' in accounting account selectors — see the Configuration section.&lt;br /&gt;
&lt;br /&gt;
== 14. Known limitations ==&lt;br /&gt;
&lt;br /&gt;
* '''Zero-decimal currencies''' (JPY, KRW…) are not handled: amounts are divided by 100 assuming two decimals. Intended use: EUR.&lt;br /&gt;
* '''The 35-day window''' is not configurable. A sync interrupted for longer must be caught up manually.&lt;br /&gt;
* '''Refund matching''' — relies on &amp;lt;code&amp;gt;ext_payment_id&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ext_payment_site&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;llx_paiement&amp;lt;/code&amp;gt;, filled in by the standard Stripe payment flow. A payment recorded any other way cannot be matched automatically. Matching goes through the '''PaymentIntent id''', never the charge id: the core Stripe module never stores the latter ''(it stores either the raw PaymentIntent, or a composite value, depending on the payment path taken)''.&lt;br /&gt;
* '''CSV import assumes French notation''': an export with a decimal point would not be parsed correctly.&lt;br /&gt;
* '''The &amp;quot;Transfer&amp;quot; column of the Payments CSV''' is stored for information only: it is not used to check that the sum of payments matches the imported payout amount.&lt;br /&gt;
* '''CSV-imported refunds always land in &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;''' — intended behaviour, not a bug.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; VAT mode''' — the Stripe account's bank balance does not reflect the fees, see section 5.&lt;br /&gt;
&lt;br /&gt;
[[Category:Dolibarr]]&lt;br /&gt;
[[Category:Modules]]&lt;br /&gt;
[[Category:Accounting]]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Stripeaccounting&amp;diff=544</id>
		<title>Stripeaccounting</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Stripeaccounting&amp;diff=544"/>
				<updated>2026-08-02T12:21:09Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:StripeAccounting — Documentation technique}}&lt;br /&gt;
&lt;br /&gt;
[[Stripeaccounting/en]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border:1px solid #c8ccd1; background:#f8f9fa; border-radius:4px; padding:1em 1.2em; margin:0 0 1.5em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''StripeAccounting''' est un module Dolibarr de '''rapprochement comptable Stripe'''.&lt;br /&gt;
&lt;br /&gt;
Il lit l'API Stripe (ou un export CSV), repère les mouvements que le module Stripe officiel ne comptabilise pas — frais, remboursements, litiges, virements — et pose les écritures manquantes.&lt;br /&gt;
&lt;br /&gt;
: '''Compatibilité''' — Dolibarr 17+, PHP 7.2 → 8.5&lt;br /&gt;
: '''Dépend de''' — modules Stripe, Banque, Comptabilité en partie double&lt;br /&gt;
: '''Voir aussi''' — [[README-fr|Installation et guide utilisateur]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== 1. Principes de fonctionnement ==&lt;br /&gt;
&lt;br /&gt;
Quatre règles gouvernent tout le module.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:22%;&amp;quot; | Principe !! Ce que ça veut dire&lt;br /&gt;
|-&lt;br /&gt;
| '''Complémentaire''' || Le module ne crée aucun paiement, aucune facture, aucun webhook. Il lit Stripe et complète la comptabilité, rien de plus.&lt;br /&gt;
|-&lt;br /&gt;
| '''Idempotent''' || Chaque objet Stripe n'est traité qu'une fois, quel que soit le nombre de relances de la synchronisation.&lt;br /&gt;
|-&lt;br /&gt;
| '''Jamais de devinette''' || Si une opération ne peut pas être rattachée avec certitude, rien n'est posté : la ligne passe en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; pour revue manuelle.&lt;br /&gt;
|-&lt;br /&gt;
| '''Configuration bloquante''' || Tant que la configuration minimale est incomplète, aucune synchronisation ne démarre (ni bouton, ni cron, ni import).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2. Prérequis ==&lt;br /&gt;
&lt;br /&gt;
=== Modules Dolibarr requis ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Module !! Ce qu'il apporte&lt;br /&gt;
|-&lt;br /&gt;
| '''Stripe''' (&amp;lt;code&amp;gt;modStripe&amp;lt;/code&amp;gt;) || Clé API, mode test/live, compte financier Stripe&lt;br /&gt;
|-&lt;br /&gt;
| '''Banque''' (&amp;lt;code&amp;gt;modBanque&amp;lt;/code&amp;gt;) || Tables &amp;lt;code&amp;gt;llx_bank&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;llx_bank_account&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| '''Comptabilité en partie double''' (&amp;lt;code&amp;gt;modAccounting&amp;lt;/code&amp;gt;) || Table &amp;lt;code&amp;gt;llx_accounting_bookkeeping&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Réglage Dolibarr indispensable ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ACCOUNTING_ACCOUNT_TRANSFER_CASH&amp;lt;/code&amp;gt; doit être renseigné dans '''Comptabilité → Configuration → Comptes par défaut'''. Sans lui, le virement interne généré par les payouts ne peut pas être transféré en comptabilité (limite de Dolibarr, pas du module).&lt;br /&gt;
&lt;br /&gt;
l’option s'appelle : '''Compte comptable par défaut pour les virements internes'''&lt;br /&gt;
&lt;br /&gt;
=== Notes ===&lt;br /&gt;
&lt;br /&gt;
* Le SDK PHP Stripe n'est pas dupliqué : le module réutilise la copie du cœur (&amp;lt;code&amp;gt;includes/stripe/stripe-php/&amp;lt;/code&amp;gt;).&lt;br /&gt;
* Le code évite volontairement toute syntaxe PHP postérieure à 7.2 (pas de &amp;lt;code&amp;gt;match&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;?-&amp;gt;&amp;lt;/code&amp;gt;, enums, propriétés typées, &amp;lt;code&amp;gt;str_contains&amp;lt;/code&amp;gt;…) pour couvrir toute la plage 7.2 → 8.5.&lt;br /&gt;
&lt;br /&gt;
== 3. Arborescence ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
custom/stripeaccounting/&lt;br /&gt;
├── core/modules/modStripeAccounting.class.php   Descripteur (droits, menus, cron, constantes)&lt;br /&gt;
├── class/&lt;br /&gt;
│   ├── StripeApi.class.php                      Wrapper SDK Stripe (lecture seule)&lt;br /&gt;
│   ├── StripeRepository.class.php               Accès SQL + idempotence&lt;br /&gt;
│   ├── StripeLogger.class.php                   Journalisation&lt;br /&gt;
│   ├── StripeAccounting.class.php               Génération des écritures&lt;br /&gt;
│   ├── StripePayout.class.php                   Rapprochement des virements&lt;br /&gt;
│   ├── StripeSync.class.php                     Orchestrateur (point d'entrée du cron)&lt;br /&gt;
│   ├── StripeCsvImporter.class.php              Import CSV&lt;br /&gt;
│   └── actions_stripeaccounting.class.php       Hook 'bankcard'&lt;br /&gt;
├── admin/setup.php                              Configuration&lt;br /&gt;
├── import.php                                   Import CSV&lt;br /&gt;
├── dashboard.php                                Tableau de bord&lt;br /&gt;
├── transaction_list.php                         Liste des transactions&lt;br /&gt;
├── cron/stripe_sync.php                         Point d'entrée CLI&lt;br /&gt;
├── lib/stripeaccounting.lib.php&lt;br /&gt;
├── sql/&lt;br /&gt;
├── langs/{fr_FR,en_US,es_ES,it_IT,de_DE}/&lt;br /&gt;
└── css/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sens des dépendances ===&lt;br /&gt;
&lt;br /&gt;
: pages et hook → &amp;lt;code&amp;gt;StripeSync&amp;lt;/code&amp;gt; → (&amp;lt;code&amp;gt;StripeApi&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StripeRepository&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StripeAccounting&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StripePayout&amp;lt;/code&amp;gt;) → &amp;lt;code&amp;gt;StripeLogger&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:26%;&amp;quot; | Classe !! Rôle&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeApi&amp;lt;/code&amp;gt; || Interroge le SDK Stripe (balance transactions, charges, remboursements, litiges, payouts) avec pagination automatique. Aucun accès base, aucune écriture.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeRepository&amp;lt;/code&amp;gt; || Tout le SQL des deux tables du module. &amp;lt;code&amp;gt;upsertTransaction()&amp;lt;/code&amp;gt; est le point d'idempotence.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeLogger&amp;lt;/code&amp;gt; || Écrit dans &amp;lt;code&amp;gt;llx_stripeaccounting_log&amp;lt;/code&amp;gt; et en miroir dans &amp;lt;code&amp;gt;dol_syslog()&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeAccounting&amp;lt;/code&amp;gt; || Construit les écritures (remboursement, litige, TVA autoliquidation) ou les mouvements bancaires (frais). Expose &amp;lt;code&amp;gt;checkConfig()&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripePayout&amp;lt;/code&amp;gt; || Crée le virement bancaire interne entre le compte Stripe et la banque réelle.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeSync&amp;lt;/code&amp;gt; || Orchestrateur : une méthode par flux, plus &amp;lt;code&amp;gt;reconcileStripeAccount()&amp;lt;/code&amp;gt; qui enchaîne tout.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeCsvImporter&amp;lt;/code&amp;gt; || Alimente le même pipeline depuis un export CSV Stripe.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ActionsStripeAccounting&amp;lt;/code&amp;gt; || Hook &amp;lt;code&amp;gt;bankcard&amp;lt;/code&amp;gt; : lien vers le tableau de bord sur la fiche du compte Stripe.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 4. Synchronisation et idempotence ==&lt;br /&gt;
&lt;br /&gt;
Chaque flux (&amp;lt;code&amp;gt;syncFees&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncRefunds&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncDisputes&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncPayouts&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncTransactions&amp;lt;/code&amp;gt;) suit toujours les mêmes étapes :&lt;br /&gt;
&lt;br /&gt;
# '''Vérifier la configuration''' — si elle est incomplète : log &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt;, arrêt immédiat, aucun appel API.&lt;br /&gt;
# '''Lister les objets Stripe''' sur une fenêtre glissante de '''35 jours'''.&lt;br /&gt;
# '''Filtrer''' — un objet est ignoré seulement s'il existe déjà ''et'' que son statut est &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;ignored&amp;lt;/code&amp;gt;. Une ligne en &amp;lt;code&amp;gt;pending&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; est '''retentée''' à ce run.&lt;br /&gt;
# '''Enregistrer''' en statut &amp;lt;code&amp;gt;pending&amp;lt;/code&amp;gt;, puis générer l'écriture ou le mouvement bancaire.&lt;br /&gt;
# '''Conclure''' — succès : statut &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt;. Échec : statut &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; avec le message, et '''le lot continue''' sur l'objet suivant.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #36c; background:#eaf3ff; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Reprise automatique''' — une ligne en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; redevient éligible au run suivant. Une fois la cause corrigée (par exemple un exercice comptable créé tardivement), aucune intervention manuelle n'est nécessaire.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi les doublons sont impossibles ===&lt;br /&gt;
&lt;br /&gt;
* '''Clé unique en base''' sur &amp;lt;code&amp;gt;(stripe_object_id, entity)&amp;lt;/code&amp;gt; — protège même contre deux exécutions concurrentes du cron.&lt;br /&gt;
* '''Test explicite avant traitement''' — évite jusqu'à la tentative d'écriture pour un objet déjà finalisé.&lt;br /&gt;
&lt;br /&gt;
=== Cas particuliers : &amp;lt;code&amp;gt;adjustment&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;payment_failure_refund&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Ce sont des corrections de solde effectuées par Stripe lui-même (réversion après litige, remboursement d'un paiement finalement échoué). Le module les '''enregistre''' — sinon elles resteraient invisibles — mais ne les comptabilise '''jamais''' automatiquement : le signe du montant et la cause varient trop. Elles sont créées directement en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, avec un message explicite, à traiter manuellement.&lt;br /&gt;
&lt;br /&gt;
== 5. Écritures comptables ==&lt;br /&gt;
&lt;br /&gt;
Toutes les lignes d'un même évènement partagent le triplet &amp;lt;code&amp;gt;doc_type='stripeaccounting'&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fk_doc&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;doc_ref&amp;lt;/code&amp;gt; : Dolibarr les regroupe automatiquement sous un même numéro de pièce, sans numérotation propre au module.&lt;br /&gt;
&lt;br /&gt;
=== Vue d'ensemble ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! Évènement !! Ce que fait le module !! Résultat comptable&lt;br /&gt;
|-&lt;br /&gt;
| Frais Stripe ''(TVA &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt;)'' || Mouvement bancaire &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; || Écriture 627xxx / 517xxx générée plus tard par Dolibarr&lt;br /&gt;
|-&lt;br /&gt;
| Frais Stripe ''(mode &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt;)'' || En plus : paire TVA postée immédiatement || Débit TVA déductible, crédit TVA autoliquidation ''(impact net nul)''&lt;br /&gt;
|-&lt;br /&gt;
| Frais Stripe ''(mode &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt;)'' || Écriture directe complète || Débit compte de frais HT + TVA déductible, crédit compte Stripe TTC&lt;br /&gt;
|-&lt;br /&gt;
| Frais d'abonnement / service ''(Radar, Billing, Connect…)'' || Mouvement bancaire &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; || Écriture générée plus tard par Dolibarr, sur le compte fournisseur Stripe&lt;br /&gt;
|-&lt;br /&gt;
| Virement (payout) || Virement bancaire interne entre les 2 comptes || Écriture générée plus tard par Dolibarr&lt;br /&gt;
|-&lt;br /&gt;
| Remboursement ''(facture retrouvée)'' || Écriture directe || Débit compte client 411xxx, crédit compte Stripe 517xxx&lt;br /&gt;
|-&lt;br /&gt;
| Remboursement ''(facture introuvable)'' || Rien || Statut &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, à traiter manuellement&lt;br /&gt;
|-&lt;br /&gt;
| Litige / chargeback || Écriture directe || Débit perte sur litiges 658xxx, crédit compte Stripe 517xxx ''(+ compte de frais si frais associés)''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi frais et virements ne génèrent pas d'écriture directe ===&lt;br /&gt;
&lt;br /&gt;
Le problème historique : quand une facture Stripe est transférée en comptabilité par le workflow standard de Dolibarr, le paiement est comptabilisé pour son montant '''brut''' — les frais sont ignorés à cette étape.&lt;br /&gt;
&lt;br /&gt;
Si le module postait ''en plus'' sa propre écriture ''et'' sa propre ligne bancaire, cette ligne resterait invisible pour &amp;lt;code&amp;gt;bankjournal.php&amp;lt;/code&amp;gt; — qui ne reconnaît que les lignes rattachées à &amp;lt;code&amp;gt;doc_type='bank'&amp;lt;/code&amp;gt;. Un administrateur transférant « normalement » le compte bancaire en comptabilité créait alors une '''seconde''' écriture pour le même mouvement.&lt;br /&gt;
&lt;br /&gt;
'''La solution retenue :''' pour les frais, les frais d'abonnement et les virements, le module ne crée plus que le '''mouvement bancaire réel''', avec les mécanismes natifs de Dolibarr. C'est ensuite le bouton natif ''« Transférer en comptabilité »'' qui produit l'écriture, comme pour n'importe quel autre mouvement bancaire. Le module ne touche donc plus du tout &amp;lt;code&amp;gt;llx_accounting_bookkeeping&amp;lt;/code&amp;gt; dans ces trois cas.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:22%;&amp;quot; | Cas !! Mécanisme natif utilisé&lt;br /&gt;
|-&lt;br /&gt;
| Frais et frais d'abonnement || &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; (mouvement bancaire avec compte de contrepartie, sans tiers ni facture), avec son propre &amp;lt;code&amp;gt;accountancy_code&amp;lt;/code&amp;gt; que &amp;lt;code&amp;gt;bankjournal.php&amp;lt;/code&amp;gt; lit directement.&lt;br /&gt;
|-&lt;br /&gt;
| Virements (payouts) || Virement interne Dolibarr : &amp;lt;code&amp;gt;Account::addline()&amp;lt;/code&amp;gt; des deux côtés, plus &amp;lt;code&amp;gt;add_url_line(…, 'banktransfert')&amp;lt;/code&amp;gt;. La contrepartie est imputée sur &amp;lt;code&amp;gt;ACCOUNTING_ACCOUNT_TRANSFER_CASH&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Dans les deux cas, le statut passe à &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt; — le module a fini son travail — mais '''&amp;lt;code&amp;gt;piece_num&amp;lt;/code&amp;gt; reste vide''' : l'écriture n'existe pas encore, seul &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; est renseigné. Après transfert manuel, on la retrouve avec &amp;lt;code&amp;gt;doc_type='bank'&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;fk_doc&amp;lt;/code&amp;gt; égal au &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; de la ligne.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #fc3; background:#fef6e7; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''À savoir''' — l'écriture des virements ne s'équilibre à zéro sur le compte de transfert que lorsque '''les deux''' comptes bancaires (Stripe ''et'' la banque réelle) ont été transférés en comptabilité, pas seulement un des deux.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #d33; background:#fee7e6; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''⚠ &amp;lt;code&amp;gt;STRIPE_AUTO_RECORD_PAYOUT&amp;lt;/code&amp;gt; doit rester désactivé'''&lt;br /&gt;
&lt;br /&gt;
Dès lors que ce module gère les virements, décochez « Activer l'enregistrement automatique des paiements Stripe » dans &amp;lt;code&amp;gt;stripe/admin/stripe.php&amp;lt;/code&amp;gt; — malgré son libellé, cette case ne concerne que les virements.&lt;br /&gt;
&lt;br /&gt;
Sinon, le webhook du module officiel et ce module créeraient chacun leur propre mouvement bancaire pour le même virement, sans le savoir l'un de l'autre.&lt;br /&gt;
&lt;br /&gt;
Le webhook cœur ne conserve d'ailleurs '''aucune''' trace de l'id du virement traité : en cas de double livraison Stripe (garantie « au moins une fois »), rien ne l'empêche de doublonner tout seul. Ce module, lui, a une vraie idempotence et rattrape automatiquement tout virement manqué sur 35 jours.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Page « Transferts Stripe » masquée ===&lt;br /&gt;
&lt;br /&gt;
À l'activation, &amp;lt;code&amp;gt;modStripeAccounting::init()&amp;lt;/code&amp;gt; désactive l'entrée de menu &amp;lt;code&amp;gt;stripe/payout.php&amp;lt;/code&amp;gt; : cette page interroge l'API en direct sans rien enregistrer, et sa coexistence avec ce module ne créerait qu'une confusion sur ce qui fait foi pour les virements. &amp;lt;code&amp;gt;remove()&amp;lt;/code&amp;gt; restaure la condition d'origine. '''C'est la seule table du cœur que ce module modifie''' — délibéré, et documenté ici pour cette raison.&lt;br /&gt;
&lt;br /&gt;
=== Frais par transaction ou frais d'abonnement ? ===&lt;br /&gt;
&lt;br /&gt;
Stripe facture deux choses distinctes sous le mot « frais » :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! !! Frais par transaction !! Frais d'abonnement / service&lt;br /&gt;
|-&lt;br /&gt;
! Exemple&lt;br /&gt;
| Commission sur chaque encaissement || Radar, Billing, Connect&lt;br /&gt;
|-&lt;br /&gt;
! Où le trouver&lt;br /&gt;
| Champ &amp;lt;code&amp;gt;.fee&amp;lt;/code&amp;gt; d'une balance transaction de type &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; || Balance transaction dédiée, de type &amp;lt;code&amp;gt;stripe_fee&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;application_fee&amp;lt;/code&amp;gt; ''(le &amp;lt;code&amp;gt;.fee&amp;lt;/code&amp;gt; y vaut toujours 0, le montant est dans &amp;lt;code&amp;gt;.amount&amp;lt;/code&amp;gt;)''&lt;br /&gt;
|-&lt;br /&gt;
! Compte utilisé&lt;br /&gt;
| Compte de frais configuré (627xxx) || Code comptable fournisseur du tiers Stripe configuré&lt;br /&gt;
|-&lt;br /&gt;
! Type en base&lt;br /&gt;
| &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Limite du mode TVA &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Ce mode doit scinder le montant TTC en HT + TVA, un découpage que &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; ne sait pas exprimer. Il reste donc sur l'ancien comportement : écriture directe complète, aucun mouvement bancaire créé. Pas de risque de doublon (puisque aucune ligne bancaire n'est produite), mais le solde &amp;lt;code&amp;gt;llx_bank&amp;lt;/code&amp;gt; du compte Stripe ne reflétera jamais les frais tant que ce mode est actif.&lt;br /&gt;
&lt;br /&gt;
== 6. Import CSV ==&lt;br /&gt;
&lt;br /&gt;
L'import couvre le cas d'un compte Stripe '''différent''' de celui configuré dans le module officiel — par exemple une autre boutique PrestaShop avec son propre compte marchand. L'API n'y a pas accès : le contenu est exporté en CSV depuis le dashboard Stripe, puis importé.&lt;br /&gt;
&lt;br /&gt;
=== Hypothèse de départ ===&lt;br /&gt;
&lt;br /&gt;
Les factures et paiements de cette boutique sont '''déjà''' comptabilisés dans Dolibarr par un autre processus, et l'encaissement (débit 517, crédit 411) est déjà posé. Seuls manquent les '''frais''', les '''remboursements''' et les '''virements''' — c'est exactement ce que l'import traite.&lt;br /&gt;
&lt;br /&gt;
=== Interface : un seul champ ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;import.php&amp;lt;/code&amp;gt; n'expose plus qu'un champ d'upload, '''Historique général''', câblé sur &amp;lt;code&amp;gt;importGeneralHistory()&amp;lt;/code&amp;gt;. Ce fichier couvre à lui seul tous les types de mouvements.&lt;br /&gt;
&lt;br /&gt;
Les méthodes &amp;lt;code&amp;gt;importPayments()&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;importPayouts()&amp;lt;/code&amp;gt; restent implémentées et fonctionnelles, mais ne sont plus atteignables depuis l'interface ; elles sont documentées ci-dessous pour mémoire.&lt;br /&gt;
&lt;br /&gt;
Comme le bouton « Synchroniser maintenant », l'import est bloqué — bandeau d'alerte, bouton désactivé, garde-fou côté serveur — tant que la configuration est incomplète.&lt;br /&gt;
&lt;br /&gt;
=== Les trois méthodes ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:24%;&amp;quot; | Méthode !! Export Stripe lu !! Traitement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;importGeneralHistory()&amp;lt;/code&amp;gt;&amp;lt;br /&amp;gt;''(seule exposée)'' || Balance history || Aiguillage par colonne &amp;lt;code&amp;gt;Type&amp;lt;/code&amp;gt;, voir tableau ci-dessous&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;importPayments()&amp;lt;/code&amp;gt; || Payments || Frais → écriture de frais. Montant remboursé → ligne &amp;lt;code&amp;gt;refund&amp;lt;/code&amp;gt; toujours en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;importPayouts()&amp;lt;/code&amp;gt; || Payouts || Exactement le même traitement qu'un payout venu de l'API&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Aiguillage de l'historique général, par colonne &amp;lt;code&amp;gt;Type&amp;lt;/code&amp;gt; :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:30%;&amp;quot; | Type Stripe !! Traitement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt; || Virement bancaire interne, comme via l'API&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;payment&amp;lt;/code&amp;gt; avec frais || Mouvement de frais&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_fee&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;application_fee&amp;lt;/code&amp;gt; || Frais d'abonnement, sur le compte fournisseur Stripe&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;refund&amp;lt;/code&amp;gt; || Enregistré, '''toujours''' en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;payout_minimum_balance_hold&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;…_release&amp;lt;/code&amp;gt; || '''Ignorés''' — réserve glissante Stripe, impact net nul, rien à comptabiliser&lt;br /&gt;
|-&lt;br /&gt;
| tout autre type || Enregistré en &amp;lt;code&amp;gt;type='other'&amp;lt;/code&amp;gt;, statut &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, type brut conservé dans la description. Aucune écriture devinée.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les colonnes sont reconnues '''par leur nom''' : l'ordre importe peu, et les colonnes en plus non utilisées sont ignorées.&lt;br /&gt;
&lt;br /&gt;
=== Idempotence de l'import ===&lt;br /&gt;
&lt;br /&gt;
La clé unique protège contre tout double import : réimporter le même CSV, ou un CSV qui chevauche un import précédent, ne crée aucun doublon.&lt;br /&gt;
&lt;br /&gt;
Point important : dans l'historique général, les lignes &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;payment&amp;lt;/code&amp;gt; sont indexées par leur colonne '''&amp;lt;code&amp;gt;Source&amp;lt;/code&amp;gt;''' (&amp;lt;code&amp;gt;po_…&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ch_…&amp;lt;/code&amp;gt;), pas par l'&amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt; de la ligne (&amp;lt;code&amp;gt;txn_…&amp;lt;/code&amp;gt;) — soit exactement la même clé que les imports dédiés. Importer l'historique général '''en plus''' des exports spécifiques ne poste donc jamais deux fois la même écriture, quel que soit l'ordre.&lt;br /&gt;
&lt;br /&gt;
Les identifiants Stripe étant uniques à l'échelle de la plateforme, mélanger dans la même table des lignes venant du compte API et de plusieurs comptes importés en CSV ne présente aucun risque de collision.&lt;br /&gt;
&lt;br /&gt;
=== Détails pratiques ===&lt;br /&gt;
&lt;br /&gt;
* '''Libellé source''' — un champ libre saisi à l'import (ex. « Boutique DRM ») est stocké sur chaque ligne créée et sert de colonne et de filtre dans la liste, pour distinguer plusieurs boutiques côte à côte.&lt;br /&gt;
* '''Format des montants''' — les CSV Stripe utilisent la virgule décimale française, convertie via &amp;lt;code&amp;gt;price2num()&amp;lt;/code&amp;gt;. Les dates marquées &amp;lt;code&amp;gt;(UTC)&amp;lt;/code&amp;gt; sont interprétées comme telles.&lt;br /&gt;
&lt;br /&gt;
== 7. Configuration ==&lt;br /&gt;
&lt;br /&gt;
La clé API et le mode test/live ne sont '''pas''' ressaisis ici : ils sont lus en lecture seule depuis le module Stripe officiel.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:26%;&amp;quot; | Champ !! Constante !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| Compte financier Stripe || &amp;lt;code&amp;gt;STRIPE_BANK_ACCOUNT_FOR_PAYMENTS&amp;lt;/code&amp;gt; ''(constante du module officiel)'' || Sélecteur de compte bancaire. Aucune copie locale, donc aucun risque de divergence.&lt;br /&gt;
|-&lt;br /&gt;
| Compte bancaire principal || &amp;lt;code&amp;gt;STRIPE_BANK_ACCOUNT_FOR_BANKTRANSFERS&amp;lt;/code&amp;gt; ''(constante du module officiel)'' || Même sélecteur. Voir l'encadré ci-dessous.&lt;br /&gt;
|-&lt;br /&gt;
| Compte de frais || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_FRAIS&amp;lt;/code&amp;gt; || Numéro de compte, ex. 627xxx&lt;br /&gt;
|-&lt;br /&gt;
| Compte de litiges || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_LITIGES&amp;lt;/code&amp;gt; || Numéro de compte, ex. 658xxx. '''Requis''' — utilisé dès qu'un litige survient, quel que soit le mode TVA.&lt;br /&gt;
|-&lt;br /&gt;
| Tiers fournisseur Stripe || &amp;lt;code&amp;gt;STRIPEACCOUNTING_FOURNISSEUR_STRIPE_ID&amp;lt;/code&amp;gt; || Tiers marqué fournisseur ; c'est son code comptable fournisseur qui est utilisé. Optionnel, sauf s'il existe des frais d'abonnement.&lt;br /&gt;
|-&lt;br /&gt;
| Mode TVA || &amp;lt;code&amp;gt;STRIPEACCOUNTING_VAT_MODE&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Compte TVA déductible (intracommunautaire) || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_TVA_DEDUCTIBLE&amp;lt;/code&amp;gt; || Requis si mode TVA ≠ &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt;. Stripe facturant toujours depuis une entité UE non française, la TVA déductible est intracommunautaire dans tous les cas.&lt;br /&gt;
|-&lt;br /&gt;
| Compte de TVA due (intracommunautaire) || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_TVA_AUTOLIQUIDATION&amp;lt;/code&amp;gt; || Requis en mode &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt; uniquement — jamais utilisé en mode &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| Taux de TVA || &amp;lt;code&amp;gt;STRIPEACCOUNTING_VAT_RATE&amp;lt;/code&amp;gt; || Pourcentage, 20 par défaut&lt;br /&gt;
|-&lt;br /&gt;
| Fréquence de synchronisation || &amp;lt;code&amp;gt;STRIPEACCOUNTING_SYNC_UNITFREQUENCY&amp;lt;/code&amp;gt; || Répercutée sur la tâche planifiée (en secondes)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #36c; background:#eaf3ff; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Pourquoi redéfinir le compte bancaire principal ici ?'''&lt;br /&gt;
&lt;br /&gt;
La page de configuration du module Stripe officiel n'affiche ce champ que si &amp;lt;code&amp;gt;STRIPE_AUTO_RECORD_PAYOUT&amp;lt;/code&amp;gt; est activé — et son handler de sauvegarde remet la valeur à 0 à chaque enregistrement tant que le champ n'est pas rendu. Or ce réglage doit justement rester désactivé quand ce module gère les virements. Le champ est donc réexposé ici, en écrivant directement la constante du cœur, pour que la valeur reste configurable et stable.&lt;br /&gt;
&lt;br /&gt;
Les deux sélecteurs de compte n'écrivent leur constante que si un compte réel a été soumis : enregistrer la page pour un tout autre champ n'écrase jamais une valeur correcte.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Vérification de la configuration ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;StripeAccounting::checkConfig()&amp;lt;/code&amp;gt; renvoie la liste des constantes manquantes. Elle est appelée à la fois par la page de configuration (bandeau d'information) et par chaque point d'entrée de synchronisation (garde-fou réel qui bloque tout traitement).&lt;br /&gt;
&lt;br /&gt;
=== Piège des sélecteurs de compte comptable ===&lt;br /&gt;
&lt;br /&gt;
Les quatre champs utilisant &amp;lt;code&amp;gt;FormAccounting::select_account()&amp;lt;/code&amp;gt; (frais, litiges, les deux comptes TVA) ont une option « rien sélectionné » dont la valeur est '''&amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;''' — une chaîne non vide, donc vraie en PHP. Un champ laissé vide et enregistré stocke littéralement &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;StripeAccounting::getAccountConst()&amp;lt;/code&amp;gt; normalise cette valeur en chaîne vide à la lecture, partout où ces constantes sont lues. Aucune écriture ne peut donc atterrir sur le compte inexistant &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 8. Interface ==&lt;br /&gt;
&lt;br /&gt;
=== Tableau de bord ===&lt;br /&gt;
&lt;br /&gt;
Solde Stripe (appel API en direct), nombre de transactions non rapprochées, total des frais du mois, payouts en attente, et bouton '''Synchroniser maintenant''' — désactivé, avec bandeau listant les constantes manquantes, tant que la configuration est incomplète.&lt;br /&gt;
&lt;br /&gt;
=== Liste des transactions ===&lt;br /&gt;
&lt;br /&gt;
Liste paginée, triable et filtrable, construite avec le même mécanisme que les listes natives Dolibarr : l'icône en haut à droite du tableau permet à chaque utilisateur de choisir ses colonnes, et la préférence est mémorisée par utilisateur.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:20%;&amp;quot; | Colonne !! Contenu&lt;br /&gt;
|-&lt;br /&gt;
| Montant, Frais, Total || Le popup sur les frais indique la TVA sur frais quand une paire d'autoliquidation ou une TVA française a été postée&lt;br /&gt;
|-&lt;br /&gt;
| Type, Description || Popup avec l'ID Stripe, l'ID d'évènement ou de source, et la description complète non tronquée&lt;br /&gt;
|-&lt;br /&gt;
| Tiers || Le client résolu via la facture, ou via la charge source pour son frais associé, ou le tiers fournisseur Stripe pour un frais d'abonnement&lt;br /&gt;
|-&lt;br /&gt;
| Écriture || Lien « Pièce n°X » vers l'écriture, et/ou lien vers le mouvement bancaire associé — voir la nuance ci-dessous&lt;br /&gt;
|-&lt;br /&gt;
| Source, Statut || Le badge &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; ouvre un popup avec le message d'erreur complet : plus besoin d'aller en base pour comprendre un échec&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #fc3; background:#fef6e7; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Lire la colonne « Écriture »''' — sur une ligne &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt;, le lien pointe vers le '''mouvement bancaire''', pas vers une pièce comptable. Le &amp;lt;code&amp;gt;piece_num&amp;lt;/code&amp;gt; du module, lui, n'est jamais l'écriture 627/517 du frais : c'est uniquement la paire TVA d'autoliquidation. L'écriture du frais est générée plus tard, par le bouton natif de Dolibarr, et n'est jamais reportée sur cette ligne.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La page est '''purement consultative''' : aucune comptabilisation manuelle n'y est proposée. Le module comptabilise automatiquement, et le transfert en comptabilité des frais et virements se fait depuis le bouton natif « Transférer en comptabilité ».&lt;br /&gt;
&lt;br /&gt;
=== Lignes &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Chaque paiement produit '''deux lignes''' en base :&lt;br /&gt;
&lt;br /&gt;
* une ligne &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt;, toujours en statut &amp;lt;code&amp;gt;ignored&amp;lt;/code&amp;gt;, frais à 0, jamais traitée — présente uniquement pour l'idempotence ;&lt;br /&gt;
* une ligne &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; pour le même paiement, liée à la première.&lt;br /&gt;
&lt;br /&gt;
Les deux apparaissent séparément dans la liste, mais la ligne &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; porte elle aussi le lien vers le paiement et la facture, résolu par jointure.&lt;br /&gt;
&lt;br /&gt;
=== Bandeau mode test ===&lt;br /&gt;
&lt;br /&gt;
Tant que le mode live n'est pas activé, le tableau de bord, la page de configuration et la liste des transactions affichent tous les trois le même avertissement que le module Stripe officiel. Impossible d'oublier qu'on travaille en mode test.&lt;br /&gt;
&lt;br /&gt;
=== Menus ===&lt;br /&gt;
&lt;br /&gt;
Tout est regroupé sous '''Banques et caisses → Compte Stripe''' (menu du module officiel), à plat, en trois entrées de même niveau :&lt;br /&gt;
&lt;br /&gt;
# Tableau de bord Stripe&lt;br /&gt;
# Transactions Stripe&lt;br /&gt;
# Import CSV ''(réservé aux administrateurs)''&lt;br /&gt;
&lt;br /&gt;
Un lien vers le tableau de bord est aussi ajouté automatiquement sur la fiche du compte bancaire configuré comme compte Stripe.&lt;br /&gt;
&lt;br /&gt;
== 9. Tâche planifiée ==&lt;br /&gt;
&lt;br /&gt;
Deux façons d'exécuter la synchronisation, toutes deux idempotentes et sans risque à relancer. Dans les deux cas le code exécuté est strictement le même : aucune divergence de comportement.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #d33; background:#fee7e6; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''⚠ Aucune des deux ne démarre toute seule.'''&lt;br /&gt;
&lt;br /&gt;
L'activation du module crée la tâche &amp;lt;code&amp;gt;StripeAccountingSync&amp;lt;/code&amp;gt;, mais '''désactivée par défaut'''. Et même activée, l'ordonnanceur Dolibarr n'est déclenché par rien tant qu'aucune crontab système ne l'appelle. Sans ces deux étapes, la synchro n'a lieu qu'au clic manuel sur « Synchroniser maintenant ».&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Étape 1 — activer la tâche ===&lt;br /&gt;
&lt;br /&gt;
Dans '''Accueil → Configuration → Modules → Tâches planifiées'''. &amp;lt;code&amp;gt;llx_cronjob&amp;lt;/code&amp;gt; étant une table du cœur, ce réglage se fait uniquement par l'interface, jamais en SQL direct depuis le module.&lt;br /&gt;
&lt;br /&gt;
=== Étape 2 — un déclencheur système ===&lt;br /&gt;
&lt;br /&gt;
Au choix, l'une des deux options.&lt;br /&gt;
&lt;br /&gt;
'''Option A — ordonnanceur Dolibarr''' ''(recommandé si plusieurs tâches planifiées coexistent)''. Lance toutes les tâches dues, pas seulement celle-ci. Nécessite l'étape 1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
*/15 * * * * curl &amp;quot;https://votre-dolibarr/public/cron/cron_run_jobs_by_url.php?securitykey=VOTRE_CLE&amp;amp;userlogin=VOTRE_LOGIN&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La clé de sécurité se génère sur la page des tâches planifiées, bouton « Sécurité de l'exécution des tâches par URL ».&lt;br /&gt;
&lt;br /&gt;
'''Option B — script CLI du module.''' Autonome, refuse l'exécution depuis un navigateur, et indépendant de l'état activé ou non de la tâche Dolibarr.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
*/15 * * * * php /chemin/vers/htdocs/custom/stripeaccounting/cron/stripe_sync.php &amp;gt;&amp;gt; /var/log/stripeaccounting.log 2&amp;gt;&amp;amp;1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 10. Journalisation et permissions ==&lt;br /&gt;
&lt;br /&gt;
=== Journalisation ===&lt;br /&gt;
&lt;br /&gt;
Chaque appel API, écriture générée, avertissement ou erreur est tracé dans &amp;lt;code&amp;gt;llx_stripeaccounting_log&amp;lt;/code&amp;gt;, consultable en base ou via le fichier de log standard Dolibarr. Niveaux : &amp;lt;code&amp;gt;DEBUG&amp;lt;/code&amp;gt; &amp;lt; &amp;lt;code&amp;gt;INFO&amp;lt;/code&amp;gt; &amp;lt; &amp;lt;code&amp;gt;WARNING&amp;lt;/code&amp;gt; &amp;lt; &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt;. La colonne &amp;lt;code&amp;gt;context&amp;lt;/code&amp;gt; contient le détail structuré en JSON (payload API, montants calculés…).&lt;br /&gt;
&lt;br /&gt;
=== Permissions ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Droit !! Contrôle&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;read&amp;lt;/code&amp;gt; || Consultation du tableau de bord et de la liste&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;write&amp;lt;/code&amp;gt; || Déclarée pour la configuration, mais non vérifiée dans le code aujourd'hui&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;reconcile&amp;lt;/code&amp;gt; || Déclenchement manuel de la synchronisation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
En pratique, &amp;lt;code&amp;gt;admin/setup.php&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;import.php&amp;lt;/code&amp;gt; ne contrôlent que le statut '''administrateur Dolibarr''', pas le droit &amp;lt;code&amp;gt;write&amp;lt;/code&amp;gt; : seuls les administrateurs peuvent configurer le module ou importer un CSV, quoi qu'il soit coché dans les permissions.&lt;br /&gt;
&lt;br /&gt;
== 11. Base de données ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;llx_stripeaccounting_transaction&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Une ligne par objet Stripe traité — charge, frais, remboursement, litige ou virement — tous dans la même table, distingués par la colonne &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:24%;&amp;quot; | Colonne !! style=&amp;quot;width:16%;&amp;quot; | Type !! Rôle&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rowid&amp;lt;/code&amp;gt; || int AI || Clé primaire&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;entity&amp;lt;/code&amp;gt; || int || Multi-société Dolibarr&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_object_id&amp;lt;/code&amp;gt; || varchar(80) || Identifiant Stripe — '''ancre d'idempotence'''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_event_id&amp;lt;/code&amp;gt; || varchar(80) || Identifiant d'évènement, informatif seulement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt; || varchar(20) || &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;refund&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;dispute&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;other&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_source_id&amp;lt;/code&amp;gt; || varchar(80) || Objet Stripe source (ex. la charge liée à un remboursement)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;source_label&amp;lt;/code&amp;gt; || varchar(80) || Libellé libre saisi à l'import CSV ; vide pour les lignes venues de l'API&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;description&amp;lt;/code&amp;gt; || varchar(255) || Libellé Stripe&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;amount&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;net&amp;lt;/code&amp;gt; || decimal(24,8) || Montants déjà convertis depuis les centimes Stripe&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;currency&amp;lt;/code&amp;gt; || varchar(3) || Code devise ISO&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;date_created&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;date_available_on&amp;lt;/code&amp;gt; || datetime || Dates côté Stripe&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_facture&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fk_paiement&amp;lt;/code&amp;gt; || int || Facture et paiement Dolibarr résolus, si trouvés&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; || int || Ligne &amp;lt;code&amp;gt;llx_bank&amp;lt;/code&amp;gt; générée ''(vide pour un frais en mode TVA &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt;)''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;piece_num&amp;lt;/code&amp;gt; || varchar(20) || Numéro de pièce comptable généré, quand il y en a un&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt; || varchar(16) || &amp;lt;code&amp;gt;pending&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ignored&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;error_message&amp;lt;/code&amp;gt; || text || Détail en cas d'erreur&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;date_creation&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;date_processed&amp;lt;/code&amp;gt; || datetime || Horodatage technique&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_user_creat&amp;lt;/code&amp;gt; || int || Utilisateur ayant déclenché le traitement&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Clé unique''' sur &amp;lt;code&amp;gt;(stripe_object_id, entity)&amp;lt;/code&amp;gt; — c'est elle qui garantit qu'un même objet Stripe ne peut jamais être inséré deux fois, même en cas d'exécutions concurrentes.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;llx_stripeaccounting_log&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Colonne !! Rôle&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;level&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;DEBUG&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;INFO&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;WARNING&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;message&amp;lt;/code&amp;gt; || Message court&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;context&amp;lt;/code&amp;gt; || Contexte structuré en JSON&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_stripeaccounting_transaction&amp;lt;/code&amp;gt; || Transaction liée, si applicable&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;datec&amp;lt;/code&amp;gt; || Horodatage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 12. Dépannage ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:26%;&amp;quot; | Symptôme !! Cause probable !! Action&lt;br /&gt;
|-&lt;br /&gt;
| Le bouton « Synchroniser maintenant » est désactivé || Configuration minimale incomplète || Compléter les champs listés dans le bandeau d'alerte de la page de configuration&lt;br /&gt;
|-&lt;br /&gt;
| Une transaction reste en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; || Écriture refusée par Dolibarr (compte inexistant, période clôturée), ou remboursement non rattaché || Lire &amp;lt;code&amp;gt;error_message&amp;lt;/code&amp;gt; sur la ligne, puis le détail dans la table de logs&lt;br /&gt;
|-&lt;br /&gt;
| Le solde Stripe ne s'affiche pas || Clé API manquante ou invalide dans le module Stripe officiel || Vérifier &amp;lt;code&amp;gt;stripe/admin/stripe.php&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Un remboursement n'est jamais rapproché || Le paiement d'origine n'a pas été retrouvé via &amp;lt;code&amp;gt;ext_payment_id&amp;lt;/code&amp;gt; || Vérifier que le paiement Stripe a bien été enregistré par le module officiel avec cet identifiant&lt;br /&gt;
|-&lt;br /&gt;
| Un &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt; reste en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; || Tiers fournisseur Stripe non renseigné, ou sans code comptable fournisseur || Renseigner le champ en configuration, et compléter la fiche du tiers&lt;br /&gt;
|-&lt;br /&gt;
| Un remboursement importé en CSV reste en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; || '''Normal et attendu''' — ce compte n'est pas relié à &amp;lt;code&amp;gt;ext_payment_id&amp;lt;/code&amp;gt; || Traiter la facture et le remboursement manuellement en comptabilité&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 13. Pièges rencontrés ==&lt;br /&gt;
&lt;br /&gt;
Notes de développement, conservées pour éviter de retomber dedans.&lt;br /&gt;
&lt;br /&gt;
* '''&amp;lt;code&amp;gt;PaymentVarious::create()&amp;lt;/code&amp;gt;''' ne met à jour &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; qu'en base, jamais sur l'objet PHP. Un &amp;lt;code&amp;gt;fetch()&amp;lt;/code&amp;gt; après &amp;lt;code&amp;gt;create()&amp;lt;/code&amp;gt; est indispensable pour récupérer la vraie valeur.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;select_comptes()&amp;lt;/code&amp;gt;''' affiche son propre HTML ''et'' retourne le nombre de comptes. L'appeler en instruction nue : l'envelopper dans &amp;lt;code&amp;gt;print&amp;lt;/code&amp;gt; réafficherait ce nombre juste après la balise select.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;master.inc.php&amp;lt;/code&amp;gt;, pas &amp;lt;code&amp;gt;main.inc.php&amp;lt;/code&amp;gt;''' pour le script CLI. Le second attend une session HTTP et, en pur CLI, se termine silencieusement — aucune sortie, aucun log, code retour 0 — dans sa redirection vers la page de connexion. L'impression trompeuse que le script « ne fait rien » plutôt qu'une vraie erreur.&lt;br /&gt;
* '''Bibliothèques du cœur''' — &amp;lt;code&amp;gt;master.inc.php&amp;lt;/code&amp;gt; ne charge pas tout ce que &amp;lt;code&amp;gt;main.inc.php&amp;lt;/code&amp;gt; charge pour le web (par exemple &amp;lt;code&amp;gt;core/lib/date.lib.php&amp;lt;/code&amp;gt;, requis par &amp;lt;code&amp;gt;BookKeeping&amp;lt;/code&amp;gt;). À inclure explicitement si le script CLI évolue.&lt;br /&gt;
* '''Option « rien sélectionné » à &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;''' dans les sélecteurs de compte comptable — voir la section Configuration.&lt;br /&gt;
&lt;br /&gt;
== 14. Limites connues ==&lt;br /&gt;
&lt;br /&gt;
* '''Devises « zéro décimale »''' (JPY, KRW…) non gérées : les montants sont divisés par 100 en supposant deux décimales. Usage prévu : EUR.&lt;br /&gt;
* '''Fenêtre de 35 jours''' non configurable. Une synchronisation interrompue plus longtemps devra être rattrapée manuellement.&lt;br /&gt;
* '''Rattachement des remboursements''' — dépend de &amp;lt;code&amp;gt;ext_payment_id&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;ext_payment_site&amp;lt;/code&amp;gt; sur &amp;lt;code&amp;gt;llx_paiement&amp;lt;/code&amp;gt;, renseignés par le flux de paiement Stripe standard. Un paiement enregistré autrement ne pourra pas être rattaché automatiquement. Le rattachement se fait via le '''PaymentIntent id''', jamais via l'id de charge : le module Stripe du cœur ne stocke jamais ce dernier ''(il y met soit le PaymentIntent brut, soit un composite, selon le chemin de paiement emprunté)''.&lt;br /&gt;
* '''Import CSV en notation française''' uniquement : un export à point décimal ne serait pas interprété correctement.&lt;br /&gt;
* '''Colonne « Transfer » du CSV Paiements''' stockée à titre informatif seulement : elle ne sert pas à vérifier que le total des paiements correspond au montant du virement importé.&lt;br /&gt;
* '''Remboursements importés en CSV toujours en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;''' — comportement voulu, pas un bug.&lt;br /&gt;
* '''Mode TVA &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt;''' — le solde bancaire du compte Stripe ne reflète pas les frais, voir section 5.&lt;br /&gt;
&lt;br /&gt;
[[Catégorie:Dolibarr]]&lt;br /&gt;
[[Catégorie:Modules]]&lt;br /&gt;
[[Catégorie:Comptabilité]]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Liste_de_nos_modules&amp;diff=543</id>
		<title>Liste de nos modules</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Liste_de_nos_modules&amp;diff=543"/>
				<updated>2026-08-02T09:26:19Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : /* Modules Dolibarr mod */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Modules Dolibarr ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;0&amp;quot; style=&amp;quot;border-collapse:collapse&amp;quot;&lt;br /&gt;
| [[Fichier:addremise_box.png|160px|thumb|left|link=Addremise|Ajoutez des remises facilement]]&lt;br /&gt;
| [[Fichier:viewmap_box.png|160px|thumb|left|link=Viewmap|Afffichez une carte de tous vos contacts]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Fichier:exportpresta_box.png|160px|thumb|left|link=Exportpresta|Exportez vos produits sur PrestShop]]&lt;br /&gt;
| [[Fichier:jaquette_addinventory.png|160px|thumb|left|link=Addinventory|Corrigez votre stock facilement]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Fichier:modEANPRODOC.png|160px|thumb|left|link=Eanprodoc|Afficher les codes-barres de vos produits dans vos documents PDF]]&lt;br /&gt;
| [[Fichier:Siladel_stripeaccounting.png|160px|thumb|left|link=Stripeaccounting|Ventilation des frais Stripe avec Dolibarr]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Modules Prestashop 1.6 &amp;amp; 1.8 ==&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;0&amp;quot; style=&amp;quot;border-collapse:collapse&amp;quot;&lt;br /&gt;
| [[Fichier:dolistock_box.png|256px|thumb|left|link=Dolistock|Synchronisez votre stock entre Dolibarr et PrestaShop]]&lt;br /&gt;
| [[Fichier:256px-bestdefaultcombination_box.png|256px|thumb|left|link=best default combination|Module Remplacer automatiquement vos déclinaisons par défaut avec stratégie]]&lt;br /&gt;
| [[Fichier:256px-bypassinvoice_box.png|256px|thumb|left|link=Bypassinvoice|Déléguer la gestion des vos factures Prestashop à Dolibarr]]&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Contact ==&lt;br /&gt;
&lt;br /&gt;
Pour toutes questions sur les produits et services, veuillez nous contacter:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Siladel.png|link=https://www.siladel.fr|Développement e-commerce sur mesure]]&lt;br /&gt;
&lt;br /&gt;
[https://www.dolistore.com/index.php?controller=search&amp;amp;search_query=siladel&amp;amp;submit_search= Catalogue de nos modules disponibles à l’achat pour Dolibarr]&lt;br /&gt;
&lt;br /&gt;
[https://www.siladel.fr/service/infogerance TMA de vos applications Web]&lt;br /&gt;
&lt;br /&gt;
[https://www.siladel.fr/service/developpement-sur-mesure Développement web sur mesure]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Liste_de_nos_modules&amp;diff=542</id>
		<title>Liste de nos modules</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Liste_de_nos_modules&amp;diff=542"/>
				<updated>2026-08-02T09:26:03Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Modules Dolibarr mod ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;0&amp;quot; style=&amp;quot;border-collapse:collapse&amp;quot;&lt;br /&gt;
| [[Fichier:addremise_box.png|160px|thumb|left|link=Addremise|Ajoutez des remises facilement]]&lt;br /&gt;
| [[Fichier:viewmap_box.png|160px|thumb|left|link=Viewmap|Afffichez une carte de tous vos contacts]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Fichier:exportpresta_box.png|160px|thumb|left|link=Exportpresta|Exportez vos produits sur PrestShop]]&lt;br /&gt;
| [[Fichier:jaquette_addinventory.png|160px|thumb|left|link=Addinventory|Corrigez votre stock facilement]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Fichier:modEANPRODOC.png|160px|thumb|left|link=Eanprodoc|Afficher les codes-barres de vos produits dans vos documents PDF]]&lt;br /&gt;
| [[Fichier:Siladel_stripeaccounting.png|160px|thumb|left|link=Stripeaccounting|Ventilation des frais Stripe avec Dolibarr]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Modules Prestashop 1.6 &amp;amp; 1.8 ==&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;0&amp;quot; style=&amp;quot;border-collapse:collapse&amp;quot;&lt;br /&gt;
| [[Fichier:dolistock_box.png|256px|thumb|left|link=Dolistock|Synchronisez votre stock entre Dolibarr et PrestaShop]]&lt;br /&gt;
| [[Fichier:256px-bestdefaultcombination_box.png|256px|thumb|left|link=best default combination|Module Remplacer automatiquement vos déclinaisons par défaut avec stratégie]]&lt;br /&gt;
| [[Fichier:256px-bypassinvoice_box.png|256px|thumb|left|link=Bypassinvoice|Déléguer la gestion des vos factures Prestashop à Dolibarr]]&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Contact ==&lt;br /&gt;
&lt;br /&gt;
Pour toutes questions sur les produits et services, veuillez nous contacter:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Siladel.png|link=https://www.siladel.fr|Développement e-commerce sur mesure]]&lt;br /&gt;
&lt;br /&gt;
[https://www.dolistore.com/index.php?controller=search&amp;amp;search_query=siladel&amp;amp;submit_search= Catalogue de nos modules disponibles à l’achat pour Dolibarr]&lt;br /&gt;
&lt;br /&gt;
[https://www.siladel.fr/service/infogerance TMA de vos applications Web]&lt;br /&gt;
&lt;br /&gt;
[https://www.siladel.fr/service/developpement-sur-mesure Développement web sur mesure]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Liste_de_nos_modules&amp;diff=541</id>
		<title>Liste de nos modules</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Liste_de_nos_modules&amp;diff=541"/>
				<updated>2026-08-02T08:56:04Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : /* Modules Dolibarr */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Modules Dolibarr ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;0&amp;quot; style=&amp;quot;border-collapse:collapse&amp;quot;&lt;br /&gt;
| [[Fichier:addremise_box.png|160px|thumb|left|link=Addremise|Ajoutez des remises facilement]]&lt;br /&gt;
| [[Fichier:viewmap_box.png|160px|thumb|left|link=Viewmap|Afffichez une carte de tous vos contacts]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Fichier:exportpresta_box.png|160px|thumb|left|link=Exportpresta|Exportez vos produits sur PrestShop]]&lt;br /&gt;
| [[Fichier:jaquette_addinventory.png|160px|thumb|left|link=Addinventory|Corrigez votre stock facilement]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Fichier:modEANPRODOC.png|160px|thumb|left|link=Eanprodoc|Afficher les codes-barres de vos produits dans vos documents PDF]]&lt;br /&gt;
| [[Fichier:Siladel_stripeaccounting.png|160px|thumb|left|link=Stripeaccounting|Ventilation des frais Stripe avec Dolibarr]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Modules Prestashop 1.6 &amp;amp; 1.8 ==&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;0&amp;quot; style=&amp;quot;border-collapse:collapse&amp;quot;&lt;br /&gt;
| [[Fichier:dolistock_box.png|256px|thumb|left|link=Dolistock|Synchronisez votre stock entre Dolibarr et PrestaShop]]&lt;br /&gt;
| [[Fichier:256px-bestdefaultcombination_box.png|256px|thumb|left|link=best default combination|Module Remplacer automatiquement vos déclinaisons par défaut avec stratégie]]&lt;br /&gt;
| [[Fichier:256px-bypassinvoice_box.png|256px|thumb|left|link=Bypassinvoice|Déléguer la gestion des vos factures Prestashop à Dolibarr]]&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Contact ==&lt;br /&gt;
&lt;br /&gt;
Pour toutes questions sur les produits et services, veuillez nous contacter:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Siladel.png|link=https://www.siladel.fr|Développement e-commerce sur mesure]]&lt;br /&gt;
&lt;br /&gt;
[https://www.dolistore.com/index.php?controller=search&amp;amp;search_query=siladel&amp;amp;submit_search= Catalogue de nos modules disponibles à l’achat pour Dolibarr]&lt;br /&gt;
&lt;br /&gt;
[https://www.siladel.fr/service/infogerance TMA de vos applications Web]&lt;br /&gt;
&lt;br /&gt;
[https://www.siladel.fr/service/developpement-sur-mesure Développement web sur mesure]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Fichier:Siladel_stripeaccounting.png&amp;diff=540</id>
		<title>Fichier:Siladel stripeaccounting.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Fichier:Siladel_stripeaccounting.png&amp;diff=540"/>
				<updated>2026-08-02T08:55:37Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=README-fr&amp;diff=539</id>
		<title>README-fr</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=README-fr&amp;diff=539"/>
				<updated>2026-08-02T08:43:08Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : Page créée avec « = STRIPEACCOUNTING POUR DOLIBARR ERP CRM =  '''STRIPEACCOUNTING''' rapproche les mouvements réels Stripe — frais (par transaction et abonnement/service), remboursements... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= STRIPEACCOUNTING POUR DOLIBARR ERP CRM =&lt;br /&gt;
&lt;br /&gt;
'''STRIPEACCOUNTING''' rapproche les mouvements réels Stripe — frais (par transaction et abonnement/service), remboursements, litiges (chargebacks) et virements (payouts) — avec le compte financier intermédiaire Stripe de Dolibarr, puis génère automatiquement les écritures comptables ou mouvements bancaires manquants.&lt;br /&gt;
&lt;br /&gt;
Ce module est complémentaire au module Stripe officiel : il ne crée jamais de paiement, de facture, de session de paiement (Checkout) ni de webhook de paiement. Il se contente de lire l'API Stripe et de comptabiliser ce que le module officiel ne couvre pas.&lt;br /&gt;
&lt;br /&gt;
== Fonctionnement ==&lt;br /&gt;
&lt;br /&gt;
# Le module récupère via l'API Stripe les ''Balance Transactions'', ''Charges'', ''Refunds'', ''Disputes'' et ''Payouts'', en réutilisant la clé API et le mode (test/live) déjà configurés par le module Stripe officiel.&lt;br /&gt;
&lt;br /&gt;
# Chaque objet Stripe est enregistré une seule fois dans sa propre table (&amp;lt;code&amp;gt;llx_stripeaccounting_transaction&amp;lt;/code&amp;gt;), identifié par son identifiant Stripe. Une transaction n'est donc jamais traitée deux fois, même si la synchronisation est relancée.&lt;br /&gt;
&lt;br /&gt;
# Pour chaque nouvel objet, le traitement comptable correspondant est automatiquement exécuté.&lt;br /&gt;
&lt;br /&gt;
## '''Frais par transaction''' et '''frais d'abonnement/service''' (Radar, Billing, Connect...) :&lt;br /&gt;
&lt;br /&gt;
### Création du mouvement bancaire correspondant sur le compte Stripe.&lt;br /&gt;
&lt;br /&gt;
### Le module ne génère pas lui-même l'écriture comptable : celle-ci est produite par le bouton natif Dolibarr ''Transférer en comptabilité''.&lt;br /&gt;
&lt;br /&gt;
### Exception : en mode TVA ''Française'', l'écriture complète (frais + TVA) est générée directement par le module.&lt;br /&gt;
&lt;br /&gt;
## '''Virements (Payouts)''' :&lt;br /&gt;
&lt;br /&gt;
### Création d'un véritable virement bancaire interne entre le compte Stripe et le compte bancaire principal.&lt;br /&gt;
&lt;br /&gt;
### L'écriture comptable est ensuite générée par le mécanisme natif de Dolibarr.&lt;br /&gt;
&lt;br /&gt;
## '''Remboursements''' :&lt;br /&gt;
&lt;br /&gt;
### Génération de l'écriture inverse de la charge d'origine lorsque la facture ou le paiement correspondant est retrouvé.&lt;br /&gt;
&lt;br /&gt;
### Sinon, la transaction est marquée pour revue manuelle.&lt;br /&gt;
&lt;br /&gt;
## '''Litiges (Chargebacks)''' :&lt;br /&gt;
&lt;br /&gt;
### Comptabilisation immédiate du montant contesté sur un compte de perte dédié.&lt;br /&gt;
&lt;br /&gt;
### Comptabilisation des frais Stripe liés au litige.&lt;br /&gt;
&lt;br /&gt;
## '''Corrections de solde Stripe''' (&amp;lt;code&amp;gt;adjustment&amp;lt;/code&amp;gt;) :&lt;br /&gt;
&lt;br /&gt;
### Les transactions sont importées afin de rester visibles.&lt;br /&gt;
&lt;br /&gt;
### Elles ne sont jamais comptabilisées automatiquement car leur nature nécessite une validation humaine.&lt;br /&gt;
&lt;br /&gt;
## '''Gestion de la TVA sur les frais''' :&lt;br /&gt;
&lt;br /&gt;
### Aucune TVA.&lt;br /&gt;
&lt;br /&gt;
### TVA française.&lt;br /&gt;
&lt;br /&gt;
### Autoliquidation intracommunautaire (génération automatique d'une paire d'écritures symétriques à impact comptable nul).&lt;br /&gt;
&lt;br /&gt;
# Un tableau de bord affiche :&lt;br /&gt;
&lt;br /&gt;
#* le solde Stripe ;&lt;br /&gt;
#* les transactions non rapprochées ;&lt;br /&gt;
#* les frais du mois ;&lt;br /&gt;
#* les payouts en attente ;&lt;br /&gt;
#* un bouton '''Synchroniser maintenant'''.&lt;br /&gt;
&lt;br /&gt;
# Une tâche planifiée (cron) peut lancer automatiquement la synchronisation selon la fréquence configurée.&lt;br /&gt;
&lt;br /&gt;
# Pour un compte Stripe non relié à l'API (par exemple une autre boutique utilisant un compte Stripe distinct), une page d'import CSV permet de traiter le fichier ''Balance history'' exporté depuis Stripe, tout en conservant les mêmes garanties d'idempotence. L'import reste désactivé tant que la configuration minimale n'est pas complète.&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
'''Accueil → Configuration → Modules → StripeAccounting'''&lt;br /&gt;
&lt;br /&gt;
Les paramètres disponibles sont :&lt;br /&gt;
&lt;br /&gt;
* '''Compte financier Stripe''' et '''Compte bancaire principal'''&lt;br /&gt;
  ** Ces sélecteurs modifient directement les constantes du module Stripe officiel afin d'éviter toute divergence de configuration.&lt;br /&gt;
* '''Compte de frais'''&lt;br /&gt;
  ** Compte comptable des commissions Stripe (exemple : &amp;lt;code&amp;gt;627xxx&amp;lt;/code&amp;gt;).&lt;br /&gt;
* '''Compte de litiges'''&lt;br /&gt;
  ** Compte comptable des pertes liées aux chargebacks (exemple : &amp;lt;code&amp;gt;658xxx&amp;lt;/code&amp;gt;).&lt;br /&gt;
* '''Tiers fournisseur Stripe'''&lt;br /&gt;
  ** Utilisé pour affecter les frais d'abonnement ou de service (Radar, Billing...) au compte fournisseur correspondant.&lt;br /&gt;
* '''Mode TVA'''&lt;br /&gt;
  ** Aucune.&lt;br /&gt;
  ** TVA française.&lt;br /&gt;
  ** Autoliquidation intracommunautaire avec taux configurable.&lt;br /&gt;
* '''Fréquence de synchronisation'''&lt;br /&gt;
  ** Fréquence d'exécution de la tâche planifiée.&lt;br /&gt;
&lt;br /&gt;
Le module refuse toute synchronisation tant que cette configuration minimale n'est pas complète afin d'éviter la génération d'écritures incomplètes ou erronées.&lt;br /&gt;
&lt;br /&gt;
{{Attention|&lt;br /&gt;
'''Ne pas activer''' l'option '''Activer l'enregistrement automatique des paiements Stripe''' du module Stripe officiel.&lt;br /&gt;
&lt;br /&gt;
Malgré son intitulé, cette option concerne uniquement les virements (''Payouts''). Elle crée un mouvement bancaire via un webhook à chaque virement Stripe.&lt;br /&gt;
&lt;br /&gt;
Comme STRIPEACCOUNTING génère déjà ces mouvements de manière idempotente, l'activation simultanée des deux mécanismes provoquerait la création de doublons.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Tâche planifiée (Cron) ==&lt;br /&gt;
&lt;br /&gt;
Lors de son activation, le module crée automatiquement une tâche planifiée nommée '''StripeAccountingSync''' dans :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Accueil → Configuration → Modules → Tâches planifiées&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deux conditions sont nécessaires pour que la synchronisation soit entièrement automatique :&lt;br /&gt;
&lt;br /&gt;
=== 1. Activer la tâche ===&lt;br /&gt;
&lt;br /&gt;
Par défaut, la tâche est créée désactivée.&lt;br /&gt;
&lt;br /&gt;
Il faut ouvrir la tâche puis cocher '''Actif'''.&lt;br /&gt;
&lt;br /&gt;
=== 2. Configurer une crontab système ===&lt;br /&gt;
&lt;br /&gt;
Deux possibilités sont proposées.&lt;br /&gt;
&lt;br /&gt;
==== Script CLI du module ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
*/15 * * * * php /chemin/vers/htdocs/custom/stripeaccounting/cron/stripe_sync.php &amp;gt;&amp;gt; /var/log/stripeaccounting.log 2&amp;gt;&amp;amp;1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Ordonnanceur générique de Dolibarr ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
*/15 * * * * curl &amp;quot;https://votre-url-dolibarr/public/cron/cron_run_jobs_by_url.php?securitykey=VOTRE_CLE&amp;amp;userlogin=VOTRE_LOGIN&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sans l'une de ces deux tâches cron, la synchronisation ne pourra être lancée que manuellement via le bouton '''Synchroniser maintenant'''.&lt;br /&gt;
&lt;br /&gt;
== Prérequis ==&lt;br /&gt;
&lt;br /&gt;
* Dolibarr 17 ou supérieur.&lt;br /&gt;
* PHP 7.2 à 8.5.&lt;br /&gt;
* Module Stripe officiel activé et configuré (clés API et compte financier).&lt;br /&gt;
* Module Comptabilité en partie double (&amp;lt;code&amp;gt;Accounting&amp;lt;/code&amp;gt;) pour la table &amp;lt;code&amp;gt;llx_accounting_bookkeeping&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Crédits ==&lt;br /&gt;
&lt;br /&gt;
STRIPEACCOUNTING est développé et maintenu par '''SILADEL'''.&lt;br /&gt;
&lt;br /&gt;
=== Licence ===&lt;br /&gt;
&lt;br /&gt;
GPL v3 ou toute version ultérieure.&lt;br /&gt;
&lt;br /&gt;
== SILADEL ==&lt;br /&gt;
&lt;br /&gt;
'''Adresse'''&lt;br /&gt;
&lt;br /&gt;
7 chemin des Coquelicots&lt;br /&gt;
&lt;br /&gt;
81990 Cambon&lt;br /&gt;
&lt;br /&gt;
France&lt;br /&gt;
&lt;br /&gt;
'''E-mail'''&lt;br /&gt;
&lt;br /&gt;
[info@siladel.fr](mailto:info@siladel.fr)&lt;br /&gt;
&lt;br /&gt;
'''Site Web'''&lt;br /&gt;
&lt;br /&gt;
https://www.siladel.fr&lt;br /&gt;
&lt;br /&gt;
== Documentation ==&lt;br /&gt;
&lt;br /&gt;
* Documentation Wiki : https://wiki.siladel.fr&lt;br /&gt;
* Support : [info@siladel.fr](mailto:info@siladel.fr)&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
Développé par '''SILADEL'''&amp;lt;br /&amp;gt;&lt;br /&gt;
Auteur : '''IGREJA David'''&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Stripeaccounting&amp;diff=538</id>
		<title>Stripeaccounting</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Stripeaccounting&amp;diff=538"/>
				<updated>2026-08-02T05:55:14Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : /* Réglage Dolibarr indispensable */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:StripeAccounting — Documentation technique}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border:1px solid #c8ccd1; background:#f8f9fa; border-radius:4px; padding:1em 1.2em; margin:0 0 1.5em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''StripeAccounting''' est un module Dolibarr de '''rapprochement comptable Stripe'''.&lt;br /&gt;
&lt;br /&gt;
Il lit l'API Stripe (ou un export CSV), repère les mouvements que le module Stripe officiel ne comptabilise pas — frais, remboursements, litiges, virements — et pose les écritures manquantes.&lt;br /&gt;
&lt;br /&gt;
: '''Compatibilité''' — Dolibarr 17+, PHP 7.2 → 8.5&lt;br /&gt;
: '''Dépend de''' — modules Stripe, Banque, Comptabilité en partie double&lt;br /&gt;
: '''Voir aussi''' — [[README-fr|Installation et guide utilisateur]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== 1. Principes de fonctionnement ==&lt;br /&gt;
&lt;br /&gt;
Quatre règles gouvernent tout le module.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:22%;&amp;quot; | Principe !! Ce que ça veut dire&lt;br /&gt;
|-&lt;br /&gt;
| '''Complémentaire''' || Le module ne crée aucun paiement, aucune facture, aucun webhook. Il lit Stripe et complète la comptabilité, rien de plus.&lt;br /&gt;
|-&lt;br /&gt;
| '''Idempotent''' || Chaque objet Stripe n'est traité qu'une fois, quel que soit le nombre de relances de la synchronisation.&lt;br /&gt;
|-&lt;br /&gt;
| '''Jamais de devinette''' || Si une opération ne peut pas être rattachée avec certitude, rien n'est posté : la ligne passe en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; pour revue manuelle.&lt;br /&gt;
|-&lt;br /&gt;
| '''Configuration bloquante''' || Tant que la configuration minimale est incomplète, aucune synchronisation ne démarre (ni bouton, ni cron, ni import).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2. Prérequis ==&lt;br /&gt;
&lt;br /&gt;
=== Modules Dolibarr requis ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Module !! Ce qu'il apporte&lt;br /&gt;
|-&lt;br /&gt;
| '''Stripe''' (&amp;lt;code&amp;gt;modStripe&amp;lt;/code&amp;gt;) || Clé API, mode test/live, compte financier Stripe&lt;br /&gt;
|-&lt;br /&gt;
| '''Banque''' (&amp;lt;code&amp;gt;modBanque&amp;lt;/code&amp;gt;) || Tables &amp;lt;code&amp;gt;llx_bank&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;llx_bank_account&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| '''Comptabilité en partie double''' (&amp;lt;code&amp;gt;modAccounting&amp;lt;/code&amp;gt;) || Table &amp;lt;code&amp;gt;llx_accounting_bookkeeping&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Réglage Dolibarr indispensable ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ACCOUNTING_ACCOUNT_TRANSFER_CASH&amp;lt;/code&amp;gt; doit être renseigné dans '''Comptabilité → Configuration → Comptes par défaut'''. Sans lui, le virement interne généré par les payouts ne peut pas être transféré en comptabilité (limite de Dolibarr, pas du module).&lt;br /&gt;
&lt;br /&gt;
l’option s'appelle : '''Compte comptable par défaut pour les virements internes'''&lt;br /&gt;
&lt;br /&gt;
=== Notes ===&lt;br /&gt;
&lt;br /&gt;
* Le SDK PHP Stripe n'est pas dupliqué : le module réutilise la copie du cœur (&amp;lt;code&amp;gt;includes/stripe/stripe-php/&amp;lt;/code&amp;gt;).&lt;br /&gt;
* Le code évite volontairement toute syntaxe PHP postérieure à 7.2 (pas de &amp;lt;code&amp;gt;match&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;?-&amp;gt;&amp;lt;/code&amp;gt;, enums, propriétés typées, &amp;lt;code&amp;gt;str_contains&amp;lt;/code&amp;gt;…) pour couvrir toute la plage 7.2 → 8.5.&lt;br /&gt;
&lt;br /&gt;
== 3. Arborescence ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
custom/stripeaccounting/&lt;br /&gt;
├── core/modules/modStripeAccounting.class.php   Descripteur (droits, menus, cron, constantes)&lt;br /&gt;
├── class/&lt;br /&gt;
│   ├── StripeApi.class.php                      Wrapper SDK Stripe (lecture seule)&lt;br /&gt;
│   ├── StripeRepository.class.php               Accès SQL + idempotence&lt;br /&gt;
│   ├── StripeLogger.class.php                   Journalisation&lt;br /&gt;
│   ├── StripeAccounting.class.php               Génération des écritures&lt;br /&gt;
│   ├── StripePayout.class.php                   Rapprochement des virements&lt;br /&gt;
│   ├── StripeSync.class.php                     Orchestrateur (point d'entrée du cron)&lt;br /&gt;
│   ├── StripeCsvImporter.class.php              Import CSV&lt;br /&gt;
│   └── actions_stripeaccounting.class.php       Hook 'bankcard'&lt;br /&gt;
├── admin/setup.php                              Configuration&lt;br /&gt;
├── import.php                                   Import CSV&lt;br /&gt;
├── dashboard.php                                Tableau de bord&lt;br /&gt;
├── transaction_list.php                         Liste des transactions&lt;br /&gt;
├── cron/stripe_sync.php                         Point d'entrée CLI&lt;br /&gt;
├── lib/stripeaccounting.lib.php&lt;br /&gt;
├── sql/&lt;br /&gt;
├── langs/{fr_FR,en_US,es_ES,it_IT,de_DE}/&lt;br /&gt;
└── css/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sens des dépendances ===&lt;br /&gt;
&lt;br /&gt;
: pages et hook → &amp;lt;code&amp;gt;StripeSync&amp;lt;/code&amp;gt; → (&amp;lt;code&amp;gt;StripeApi&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StripeRepository&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StripeAccounting&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StripePayout&amp;lt;/code&amp;gt;) → &amp;lt;code&amp;gt;StripeLogger&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:26%;&amp;quot; | Classe !! Rôle&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeApi&amp;lt;/code&amp;gt; || Interroge le SDK Stripe (balance transactions, charges, remboursements, litiges, payouts) avec pagination automatique. Aucun accès base, aucune écriture.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeRepository&amp;lt;/code&amp;gt; || Tout le SQL des deux tables du module. &amp;lt;code&amp;gt;upsertTransaction()&amp;lt;/code&amp;gt; est le point d'idempotence.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeLogger&amp;lt;/code&amp;gt; || Écrit dans &amp;lt;code&amp;gt;llx_stripeaccounting_log&amp;lt;/code&amp;gt; et en miroir dans &amp;lt;code&amp;gt;dol_syslog()&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeAccounting&amp;lt;/code&amp;gt; || Construit les écritures (remboursement, litige, TVA autoliquidation) ou les mouvements bancaires (frais). Expose &amp;lt;code&amp;gt;checkConfig()&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripePayout&amp;lt;/code&amp;gt; || Crée le virement bancaire interne entre le compte Stripe et la banque réelle.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeSync&amp;lt;/code&amp;gt; || Orchestrateur : une méthode par flux, plus &amp;lt;code&amp;gt;reconcileStripeAccount()&amp;lt;/code&amp;gt; qui enchaîne tout.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeCsvImporter&amp;lt;/code&amp;gt; || Alimente le même pipeline depuis un export CSV Stripe.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ActionsStripeAccounting&amp;lt;/code&amp;gt; || Hook &amp;lt;code&amp;gt;bankcard&amp;lt;/code&amp;gt; : lien vers le tableau de bord sur la fiche du compte Stripe.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 4. Synchronisation et idempotence ==&lt;br /&gt;
&lt;br /&gt;
Chaque flux (&amp;lt;code&amp;gt;syncFees&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncRefunds&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncDisputes&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncPayouts&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncTransactions&amp;lt;/code&amp;gt;) suit toujours les mêmes étapes :&lt;br /&gt;
&lt;br /&gt;
# '''Vérifier la configuration''' — si elle est incomplète : log &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt;, arrêt immédiat, aucun appel API.&lt;br /&gt;
# '''Lister les objets Stripe''' sur une fenêtre glissante de '''35 jours'''.&lt;br /&gt;
# '''Filtrer''' — un objet est ignoré seulement s'il existe déjà ''et'' que son statut est &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;ignored&amp;lt;/code&amp;gt;. Une ligne en &amp;lt;code&amp;gt;pending&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; est '''retentée''' à ce run.&lt;br /&gt;
# '''Enregistrer''' en statut &amp;lt;code&amp;gt;pending&amp;lt;/code&amp;gt;, puis générer l'écriture ou le mouvement bancaire.&lt;br /&gt;
# '''Conclure''' — succès : statut &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt;. Échec : statut &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; avec le message, et '''le lot continue''' sur l'objet suivant.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #36c; background:#eaf3ff; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Reprise automatique''' — une ligne en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; redevient éligible au run suivant. Une fois la cause corrigée (par exemple un exercice comptable créé tardivement), aucune intervention manuelle n'est nécessaire.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi les doublons sont impossibles ===&lt;br /&gt;
&lt;br /&gt;
* '''Clé unique en base''' sur &amp;lt;code&amp;gt;(stripe_object_id, entity)&amp;lt;/code&amp;gt; — protège même contre deux exécutions concurrentes du cron.&lt;br /&gt;
* '''Test explicite avant traitement''' — évite jusqu'à la tentative d'écriture pour un objet déjà finalisé.&lt;br /&gt;
&lt;br /&gt;
=== Cas particuliers : &amp;lt;code&amp;gt;adjustment&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;payment_failure_refund&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Ce sont des corrections de solde effectuées par Stripe lui-même (réversion après litige, remboursement d'un paiement finalement échoué). Le module les '''enregistre''' — sinon elles resteraient invisibles — mais ne les comptabilise '''jamais''' automatiquement : le signe du montant et la cause varient trop. Elles sont créées directement en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, avec un message explicite, à traiter manuellement.&lt;br /&gt;
&lt;br /&gt;
== 5. Écritures comptables ==&lt;br /&gt;
&lt;br /&gt;
Toutes les lignes d'un même évènement partagent le triplet &amp;lt;code&amp;gt;doc_type='stripeaccounting'&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fk_doc&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;doc_ref&amp;lt;/code&amp;gt; : Dolibarr les regroupe automatiquement sous un même numéro de pièce, sans numérotation propre au module.&lt;br /&gt;
&lt;br /&gt;
=== Vue d'ensemble ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! Évènement !! Ce que fait le module !! Résultat comptable&lt;br /&gt;
|-&lt;br /&gt;
| Frais Stripe ''(TVA &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt;)'' || Mouvement bancaire &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; || Écriture 627xxx / 517xxx générée plus tard par Dolibarr&lt;br /&gt;
|-&lt;br /&gt;
| Frais Stripe ''(mode &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt;)'' || En plus : paire TVA postée immédiatement || Débit TVA déductible, crédit TVA autoliquidation ''(impact net nul)''&lt;br /&gt;
|-&lt;br /&gt;
| Frais Stripe ''(mode &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt;)'' || Écriture directe complète || Débit compte de frais HT + TVA déductible, crédit compte Stripe TTC&lt;br /&gt;
|-&lt;br /&gt;
| Frais d'abonnement / service ''(Radar, Billing, Connect…)'' || Mouvement bancaire &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; || Écriture générée plus tard par Dolibarr, sur le compte fournisseur Stripe&lt;br /&gt;
|-&lt;br /&gt;
| Virement (payout) || Virement bancaire interne entre les 2 comptes || Écriture générée plus tard par Dolibarr&lt;br /&gt;
|-&lt;br /&gt;
| Remboursement ''(facture retrouvée)'' || Écriture directe || Débit compte client 411xxx, crédit compte Stripe 517xxx&lt;br /&gt;
|-&lt;br /&gt;
| Remboursement ''(facture introuvable)'' || Rien || Statut &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, à traiter manuellement&lt;br /&gt;
|-&lt;br /&gt;
| Litige / chargeback || Écriture directe || Débit perte sur litiges 658xxx, crédit compte Stripe 517xxx ''(+ compte de frais si frais associés)''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi frais et virements ne génèrent pas d'écriture directe ===&lt;br /&gt;
&lt;br /&gt;
Le problème historique : quand une facture Stripe est transférée en comptabilité par le workflow standard de Dolibarr, le paiement est comptabilisé pour son montant '''brut''' — les frais sont ignorés à cette étape.&lt;br /&gt;
&lt;br /&gt;
Si le module postait ''en plus'' sa propre écriture ''et'' sa propre ligne bancaire, cette ligne resterait invisible pour &amp;lt;code&amp;gt;bankjournal.php&amp;lt;/code&amp;gt; — qui ne reconnaît que les lignes rattachées à &amp;lt;code&amp;gt;doc_type='bank'&amp;lt;/code&amp;gt;. Un administrateur transférant « normalement » le compte bancaire en comptabilité créait alors une '''seconde''' écriture pour le même mouvement.&lt;br /&gt;
&lt;br /&gt;
'''La solution retenue :''' pour les frais, les frais d'abonnement et les virements, le module ne crée plus que le '''mouvement bancaire réel''', avec les mécanismes natifs de Dolibarr. C'est ensuite le bouton natif ''« Transférer en comptabilité »'' qui produit l'écriture, comme pour n'importe quel autre mouvement bancaire. Le module ne touche donc plus du tout &amp;lt;code&amp;gt;llx_accounting_bookkeeping&amp;lt;/code&amp;gt; dans ces trois cas.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:22%;&amp;quot; | Cas !! Mécanisme natif utilisé&lt;br /&gt;
|-&lt;br /&gt;
| Frais et frais d'abonnement || &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; (mouvement bancaire avec compte de contrepartie, sans tiers ni facture), avec son propre &amp;lt;code&amp;gt;accountancy_code&amp;lt;/code&amp;gt; que &amp;lt;code&amp;gt;bankjournal.php&amp;lt;/code&amp;gt; lit directement.&lt;br /&gt;
|-&lt;br /&gt;
| Virements (payouts) || Virement interne Dolibarr : &amp;lt;code&amp;gt;Account::addline()&amp;lt;/code&amp;gt; des deux côtés, plus &amp;lt;code&amp;gt;add_url_line(…, 'banktransfert')&amp;lt;/code&amp;gt;. La contrepartie est imputée sur &amp;lt;code&amp;gt;ACCOUNTING_ACCOUNT_TRANSFER_CASH&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Dans les deux cas, le statut passe à &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt; — le module a fini son travail — mais '''&amp;lt;code&amp;gt;piece_num&amp;lt;/code&amp;gt; reste vide''' : l'écriture n'existe pas encore, seul &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; est renseigné. Après transfert manuel, on la retrouve avec &amp;lt;code&amp;gt;doc_type='bank'&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;fk_doc&amp;lt;/code&amp;gt; égal au &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; de la ligne.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #fc3; background:#fef6e7; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''À savoir''' — l'écriture des virements ne s'équilibre à zéro sur le compte de transfert que lorsque '''les deux''' comptes bancaires (Stripe ''et'' la banque réelle) ont été transférés en comptabilité, pas seulement un des deux.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #d33; background:#fee7e6; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''⚠ &amp;lt;code&amp;gt;STRIPE_AUTO_RECORD_PAYOUT&amp;lt;/code&amp;gt; doit rester désactivé'''&lt;br /&gt;
&lt;br /&gt;
Dès lors que ce module gère les virements, décochez « Activer l'enregistrement automatique des paiements Stripe » dans &amp;lt;code&amp;gt;stripe/admin/stripe.php&amp;lt;/code&amp;gt; — malgré son libellé, cette case ne concerne que les virements.&lt;br /&gt;
&lt;br /&gt;
Sinon, le webhook du module officiel et ce module créeraient chacun leur propre mouvement bancaire pour le même virement, sans le savoir l'un de l'autre.&lt;br /&gt;
&lt;br /&gt;
Le webhook cœur ne conserve d'ailleurs '''aucune''' trace de l'id du virement traité : en cas de double livraison Stripe (garantie « au moins une fois »), rien ne l'empêche de doublonner tout seul. Ce module, lui, a une vraie idempotence et rattrape automatiquement tout virement manqué sur 35 jours.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Page « Transferts Stripe » masquée ===&lt;br /&gt;
&lt;br /&gt;
À l'activation, &amp;lt;code&amp;gt;modStripeAccounting::init()&amp;lt;/code&amp;gt; désactive l'entrée de menu &amp;lt;code&amp;gt;stripe/payout.php&amp;lt;/code&amp;gt; : cette page interroge l'API en direct sans rien enregistrer, et sa coexistence avec ce module ne créerait qu'une confusion sur ce qui fait foi pour les virements. &amp;lt;code&amp;gt;remove()&amp;lt;/code&amp;gt; restaure la condition d'origine. '''C'est la seule table du cœur que ce module modifie''' — délibéré, et documenté ici pour cette raison.&lt;br /&gt;
&lt;br /&gt;
=== Frais par transaction ou frais d'abonnement ? ===&lt;br /&gt;
&lt;br /&gt;
Stripe facture deux choses distinctes sous le mot « frais » :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! !! Frais par transaction !! Frais d'abonnement / service&lt;br /&gt;
|-&lt;br /&gt;
! Exemple&lt;br /&gt;
| Commission sur chaque encaissement || Radar, Billing, Connect&lt;br /&gt;
|-&lt;br /&gt;
! Où le trouver&lt;br /&gt;
| Champ &amp;lt;code&amp;gt;.fee&amp;lt;/code&amp;gt; d'une balance transaction de type &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; || Balance transaction dédiée, de type &amp;lt;code&amp;gt;stripe_fee&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;application_fee&amp;lt;/code&amp;gt; ''(le &amp;lt;code&amp;gt;.fee&amp;lt;/code&amp;gt; y vaut toujours 0, le montant est dans &amp;lt;code&amp;gt;.amount&amp;lt;/code&amp;gt;)''&lt;br /&gt;
|-&lt;br /&gt;
! Compte utilisé&lt;br /&gt;
| Compte de frais configuré (627xxx) || Code comptable fournisseur du tiers Stripe configuré&lt;br /&gt;
|-&lt;br /&gt;
! Type en base&lt;br /&gt;
| &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Limite du mode TVA &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Ce mode doit scinder le montant TTC en HT + TVA, un découpage que &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; ne sait pas exprimer. Il reste donc sur l'ancien comportement : écriture directe complète, aucun mouvement bancaire créé. Pas de risque de doublon (puisque aucune ligne bancaire n'est produite), mais le solde &amp;lt;code&amp;gt;llx_bank&amp;lt;/code&amp;gt; du compte Stripe ne reflétera jamais les frais tant que ce mode est actif.&lt;br /&gt;
&lt;br /&gt;
== 6. Import CSV ==&lt;br /&gt;
&lt;br /&gt;
L'import couvre le cas d'un compte Stripe '''différent''' de celui configuré dans le module officiel — par exemple une autre boutique PrestaShop avec son propre compte marchand. L'API n'y a pas accès : le contenu est exporté en CSV depuis le dashboard Stripe, puis importé.&lt;br /&gt;
&lt;br /&gt;
=== Hypothèse de départ ===&lt;br /&gt;
&lt;br /&gt;
Les factures et paiements de cette boutique sont '''déjà''' comptabilisés dans Dolibarr par un autre processus, et l'encaissement (débit 517, crédit 411) est déjà posé. Seuls manquent les '''frais''', les '''remboursements''' et les '''virements''' — c'est exactement ce que l'import traite.&lt;br /&gt;
&lt;br /&gt;
=== Interface : un seul champ ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;import.php&amp;lt;/code&amp;gt; n'expose plus qu'un champ d'upload, '''Historique général''', câblé sur &amp;lt;code&amp;gt;importGeneralHistory()&amp;lt;/code&amp;gt;. Ce fichier couvre à lui seul tous les types de mouvements.&lt;br /&gt;
&lt;br /&gt;
Les méthodes &amp;lt;code&amp;gt;importPayments()&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;importPayouts()&amp;lt;/code&amp;gt; restent implémentées et fonctionnelles, mais ne sont plus atteignables depuis l'interface ; elles sont documentées ci-dessous pour mémoire.&lt;br /&gt;
&lt;br /&gt;
Comme le bouton « Synchroniser maintenant », l'import est bloqué — bandeau d'alerte, bouton désactivé, garde-fou côté serveur — tant que la configuration est incomplète.&lt;br /&gt;
&lt;br /&gt;
=== Les trois méthodes ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:24%;&amp;quot; | Méthode !! Export Stripe lu !! Traitement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;importGeneralHistory()&amp;lt;/code&amp;gt;&amp;lt;br /&amp;gt;''(seule exposée)'' || Balance history || Aiguillage par colonne &amp;lt;code&amp;gt;Type&amp;lt;/code&amp;gt;, voir tableau ci-dessous&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;importPayments()&amp;lt;/code&amp;gt; || Payments || Frais → écriture de frais. Montant remboursé → ligne &amp;lt;code&amp;gt;refund&amp;lt;/code&amp;gt; toujours en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;importPayouts()&amp;lt;/code&amp;gt; || Payouts || Exactement le même traitement qu'un payout venu de l'API&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Aiguillage de l'historique général, par colonne &amp;lt;code&amp;gt;Type&amp;lt;/code&amp;gt; :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:30%;&amp;quot; | Type Stripe !! Traitement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt; || Virement bancaire interne, comme via l'API&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;payment&amp;lt;/code&amp;gt; avec frais || Mouvement de frais&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_fee&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;application_fee&amp;lt;/code&amp;gt; || Frais d'abonnement, sur le compte fournisseur Stripe&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;refund&amp;lt;/code&amp;gt; || Enregistré, '''toujours''' en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;payout_minimum_balance_hold&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;…_release&amp;lt;/code&amp;gt; || '''Ignorés''' — réserve glissante Stripe, impact net nul, rien à comptabiliser&lt;br /&gt;
|-&lt;br /&gt;
| tout autre type || Enregistré en &amp;lt;code&amp;gt;type='other'&amp;lt;/code&amp;gt;, statut &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, type brut conservé dans la description. Aucune écriture devinée.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les colonnes sont reconnues '''par leur nom''' : l'ordre importe peu, et les colonnes en plus non utilisées sont ignorées.&lt;br /&gt;
&lt;br /&gt;
=== Idempotence de l'import ===&lt;br /&gt;
&lt;br /&gt;
La clé unique protège contre tout double import : réimporter le même CSV, ou un CSV qui chevauche un import précédent, ne crée aucun doublon.&lt;br /&gt;
&lt;br /&gt;
Point important : dans l'historique général, les lignes &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;payment&amp;lt;/code&amp;gt; sont indexées par leur colonne '''&amp;lt;code&amp;gt;Source&amp;lt;/code&amp;gt;''' (&amp;lt;code&amp;gt;po_…&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ch_…&amp;lt;/code&amp;gt;), pas par l'&amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt; de la ligne (&amp;lt;code&amp;gt;txn_…&amp;lt;/code&amp;gt;) — soit exactement la même clé que les imports dédiés. Importer l'historique général '''en plus''' des exports spécifiques ne poste donc jamais deux fois la même écriture, quel que soit l'ordre.&lt;br /&gt;
&lt;br /&gt;
Les identifiants Stripe étant uniques à l'échelle de la plateforme, mélanger dans la même table des lignes venant du compte API et de plusieurs comptes importés en CSV ne présente aucun risque de collision.&lt;br /&gt;
&lt;br /&gt;
=== Détails pratiques ===&lt;br /&gt;
&lt;br /&gt;
* '''Libellé source''' — un champ libre saisi à l'import (ex. « Boutique DRM ») est stocké sur chaque ligne créée et sert de colonne et de filtre dans la liste, pour distinguer plusieurs boutiques côte à côte.&lt;br /&gt;
* '''Format des montants''' — les CSV Stripe utilisent la virgule décimale française, convertie via &amp;lt;code&amp;gt;price2num()&amp;lt;/code&amp;gt;. Les dates marquées &amp;lt;code&amp;gt;(UTC)&amp;lt;/code&amp;gt; sont interprétées comme telles.&lt;br /&gt;
&lt;br /&gt;
== 7. Configuration ==&lt;br /&gt;
&lt;br /&gt;
La clé API et le mode test/live ne sont '''pas''' ressaisis ici : ils sont lus en lecture seule depuis le module Stripe officiel.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:26%;&amp;quot; | Champ !! Constante !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| Compte financier Stripe || &amp;lt;code&amp;gt;STRIPE_BANK_ACCOUNT_FOR_PAYMENTS&amp;lt;/code&amp;gt; ''(constante du module officiel)'' || Sélecteur de compte bancaire. Aucune copie locale, donc aucun risque de divergence.&lt;br /&gt;
|-&lt;br /&gt;
| Compte bancaire principal || &amp;lt;code&amp;gt;STRIPE_BANK_ACCOUNT_FOR_BANKTRANSFERS&amp;lt;/code&amp;gt; ''(constante du module officiel)'' || Même sélecteur. Voir l'encadré ci-dessous.&lt;br /&gt;
|-&lt;br /&gt;
| Compte de frais || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_FRAIS&amp;lt;/code&amp;gt; || Numéro de compte, ex. 627xxx&lt;br /&gt;
|-&lt;br /&gt;
| Compte de litiges || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_LITIGES&amp;lt;/code&amp;gt; || Numéro de compte, ex. 658xxx. '''Requis''' — utilisé dès qu'un litige survient, quel que soit le mode TVA.&lt;br /&gt;
|-&lt;br /&gt;
| Tiers fournisseur Stripe || &amp;lt;code&amp;gt;STRIPEACCOUNTING_FOURNISSEUR_STRIPE_ID&amp;lt;/code&amp;gt; || Tiers marqué fournisseur ; c'est son code comptable fournisseur qui est utilisé. Optionnel, sauf s'il existe des frais d'abonnement.&lt;br /&gt;
|-&lt;br /&gt;
| Mode TVA || &amp;lt;code&amp;gt;STRIPEACCOUNTING_VAT_MODE&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Compte TVA déductible (intracommunautaire) || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_TVA_DEDUCTIBLE&amp;lt;/code&amp;gt; || Requis si mode TVA ≠ &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt;. Stripe facturant toujours depuis une entité UE non française, la TVA déductible est intracommunautaire dans tous les cas.&lt;br /&gt;
|-&lt;br /&gt;
| Compte de TVA due (intracommunautaire) || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_TVA_AUTOLIQUIDATION&amp;lt;/code&amp;gt; || Requis en mode &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt; uniquement — jamais utilisé en mode &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| Taux de TVA || &amp;lt;code&amp;gt;STRIPEACCOUNTING_VAT_RATE&amp;lt;/code&amp;gt; || Pourcentage, 20 par défaut&lt;br /&gt;
|-&lt;br /&gt;
| Fréquence de synchronisation || &amp;lt;code&amp;gt;STRIPEACCOUNTING_SYNC_UNITFREQUENCY&amp;lt;/code&amp;gt; || Répercutée sur la tâche planifiée (en secondes)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #36c; background:#eaf3ff; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Pourquoi redéfinir le compte bancaire principal ici ?'''&lt;br /&gt;
&lt;br /&gt;
La page de configuration du module Stripe officiel n'affiche ce champ que si &amp;lt;code&amp;gt;STRIPE_AUTO_RECORD_PAYOUT&amp;lt;/code&amp;gt; est activé — et son handler de sauvegarde remet la valeur à 0 à chaque enregistrement tant que le champ n'est pas rendu. Or ce réglage doit justement rester désactivé quand ce module gère les virements. Le champ est donc réexposé ici, en écrivant directement la constante du cœur, pour que la valeur reste configurable et stable.&lt;br /&gt;
&lt;br /&gt;
Les deux sélecteurs de compte n'écrivent leur constante que si un compte réel a été soumis : enregistrer la page pour un tout autre champ n'écrase jamais une valeur correcte.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Vérification de la configuration ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;StripeAccounting::checkConfig()&amp;lt;/code&amp;gt; renvoie la liste des constantes manquantes. Elle est appelée à la fois par la page de configuration (bandeau d'information) et par chaque point d'entrée de synchronisation (garde-fou réel qui bloque tout traitement).&lt;br /&gt;
&lt;br /&gt;
=== Piège des sélecteurs de compte comptable ===&lt;br /&gt;
&lt;br /&gt;
Les quatre champs utilisant &amp;lt;code&amp;gt;FormAccounting::select_account()&amp;lt;/code&amp;gt; (frais, litiges, les deux comptes TVA) ont une option « rien sélectionné » dont la valeur est '''&amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;''' — une chaîne non vide, donc vraie en PHP. Un champ laissé vide et enregistré stocke littéralement &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;StripeAccounting::getAccountConst()&amp;lt;/code&amp;gt; normalise cette valeur en chaîne vide à la lecture, partout où ces constantes sont lues. Aucune écriture ne peut donc atterrir sur le compte inexistant &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 8. Interface ==&lt;br /&gt;
&lt;br /&gt;
=== Tableau de bord ===&lt;br /&gt;
&lt;br /&gt;
Solde Stripe (appel API en direct), nombre de transactions non rapprochées, total des frais du mois, payouts en attente, et bouton '''Synchroniser maintenant''' — désactivé, avec bandeau listant les constantes manquantes, tant que la configuration est incomplète.&lt;br /&gt;
&lt;br /&gt;
=== Liste des transactions ===&lt;br /&gt;
&lt;br /&gt;
Liste paginée, triable et filtrable, construite avec le même mécanisme que les listes natives Dolibarr : l'icône en haut à droite du tableau permet à chaque utilisateur de choisir ses colonnes, et la préférence est mémorisée par utilisateur.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:20%;&amp;quot; | Colonne !! Contenu&lt;br /&gt;
|-&lt;br /&gt;
| Montant, Frais, Total || Le popup sur les frais indique la TVA sur frais quand une paire d'autoliquidation ou une TVA française a été postée&lt;br /&gt;
|-&lt;br /&gt;
| Type, Description || Popup avec l'ID Stripe, l'ID d'évènement ou de source, et la description complète non tronquée&lt;br /&gt;
|-&lt;br /&gt;
| Tiers || Le client résolu via la facture, ou via la charge source pour son frais associé, ou le tiers fournisseur Stripe pour un frais d'abonnement&lt;br /&gt;
|-&lt;br /&gt;
| Écriture || Lien « Pièce n°X » vers l'écriture, et/ou lien vers le mouvement bancaire associé — voir la nuance ci-dessous&lt;br /&gt;
|-&lt;br /&gt;
| Source, Statut || Le badge &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; ouvre un popup avec le message d'erreur complet : plus besoin d'aller en base pour comprendre un échec&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #fc3; background:#fef6e7; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Lire la colonne « Écriture »''' — sur une ligne &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt;, le lien pointe vers le '''mouvement bancaire''', pas vers une pièce comptable. Le &amp;lt;code&amp;gt;piece_num&amp;lt;/code&amp;gt; du module, lui, n'est jamais l'écriture 627/517 du frais : c'est uniquement la paire TVA d'autoliquidation. L'écriture du frais est générée plus tard, par le bouton natif de Dolibarr, et n'est jamais reportée sur cette ligne.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La page est '''purement consultative''' : aucune comptabilisation manuelle n'y est proposée. Le module comptabilise automatiquement, et le transfert en comptabilité des frais et virements se fait depuis le bouton natif « Transférer en comptabilité ».&lt;br /&gt;
&lt;br /&gt;
=== Lignes &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Chaque paiement produit '''deux lignes''' en base :&lt;br /&gt;
&lt;br /&gt;
* une ligne &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt;, toujours en statut &amp;lt;code&amp;gt;ignored&amp;lt;/code&amp;gt;, frais à 0, jamais traitée — présente uniquement pour l'idempotence ;&lt;br /&gt;
* une ligne &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; pour le même paiement, liée à la première.&lt;br /&gt;
&lt;br /&gt;
Les deux apparaissent séparément dans la liste, mais la ligne &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; porte elle aussi le lien vers le paiement et la facture, résolu par jointure.&lt;br /&gt;
&lt;br /&gt;
=== Bandeau mode test ===&lt;br /&gt;
&lt;br /&gt;
Tant que le mode live n'est pas activé, le tableau de bord, la page de configuration et la liste des transactions affichent tous les trois le même avertissement que le module Stripe officiel. Impossible d'oublier qu'on travaille en mode test.&lt;br /&gt;
&lt;br /&gt;
=== Menus ===&lt;br /&gt;
&lt;br /&gt;
Tout est regroupé sous '''Banques et caisses → Compte Stripe''' (menu du module officiel), à plat, en trois entrées de même niveau :&lt;br /&gt;
&lt;br /&gt;
# Tableau de bord Stripe&lt;br /&gt;
# Transactions Stripe&lt;br /&gt;
# Import CSV ''(réservé aux administrateurs)''&lt;br /&gt;
&lt;br /&gt;
Un lien vers le tableau de bord est aussi ajouté automatiquement sur la fiche du compte bancaire configuré comme compte Stripe.&lt;br /&gt;
&lt;br /&gt;
== 9. Tâche planifiée ==&lt;br /&gt;
&lt;br /&gt;
Deux façons d'exécuter la synchronisation, toutes deux idempotentes et sans risque à relancer. Dans les deux cas le code exécuté est strictement le même : aucune divergence de comportement.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #d33; background:#fee7e6; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''⚠ Aucune des deux ne démarre toute seule.'''&lt;br /&gt;
&lt;br /&gt;
L'activation du module crée la tâche &amp;lt;code&amp;gt;StripeAccountingSync&amp;lt;/code&amp;gt;, mais '''désactivée par défaut'''. Et même activée, l'ordonnanceur Dolibarr n'est déclenché par rien tant qu'aucune crontab système ne l'appelle. Sans ces deux étapes, la synchro n'a lieu qu'au clic manuel sur « Synchroniser maintenant ».&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Étape 1 — activer la tâche ===&lt;br /&gt;
&lt;br /&gt;
Dans '''Accueil → Configuration → Modules → Tâches planifiées'''. &amp;lt;code&amp;gt;llx_cronjob&amp;lt;/code&amp;gt; étant une table du cœur, ce réglage se fait uniquement par l'interface, jamais en SQL direct depuis le module.&lt;br /&gt;
&lt;br /&gt;
=== Étape 2 — un déclencheur système ===&lt;br /&gt;
&lt;br /&gt;
Au choix, l'une des deux options.&lt;br /&gt;
&lt;br /&gt;
'''Option A — ordonnanceur Dolibarr''' ''(recommandé si plusieurs tâches planifiées coexistent)''. Lance toutes les tâches dues, pas seulement celle-ci. Nécessite l'étape 1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
*/15 * * * * curl &amp;quot;https://votre-dolibarr/public/cron/cron_run_jobs_by_url.php?securitykey=VOTRE_CLE&amp;amp;userlogin=VOTRE_LOGIN&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La clé de sécurité se génère sur la page des tâches planifiées, bouton « Sécurité de l'exécution des tâches par URL ».&lt;br /&gt;
&lt;br /&gt;
'''Option B — script CLI du module.''' Autonome, refuse l'exécution depuis un navigateur, et indépendant de l'état activé ou non de la tâche Dolibarr.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
*/15 * * * * php /chemin/vers/htdocs/custom/stripeaccounting/cron/stripe_sync.php &amp;gt;&amp;gt; /var/log/stripeaccounting.log 2&amp;gt;&amp;amp;1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 10. Journalisation et permissions ==&lt;br /&gt;
&lt;br /&gt;
=== Journalisation ===&lt;br /&gt;
&lt;br /&gt;
Chaque appel API, écriture générée, avertissement ou erreur est tracé dans &amp;lt;code&amp;gt;llx_stripeaccounting_log&amp;lt;/code&amp;gt;, consultable en base ou via le fichier de log standard Dolibarr. Niveaux : &amp;lt;code&amp;gt;DEBUG&amp;lt;/code&amp;gt; &amp;lt; &amp;lt;code&amp;gt;INFO&amp;lt;/code&amp;gt; &amp;lt; &amp;lt;code&amp;gt;WARNING&amp;lt;/code&amp;gt; &amp;lt; &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt;. La colonne &amp;lt;code&amp;gt;context&amp;lt;/code&amp;gt; contient le détail structuré en JSON (payload API, montants calculés…).&lt;br /&gt;
&lt;br /&gt;
=== Permissions ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Droit !! Contrôle&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;read&amp;lt;/code&amp;gt; || Consultation du tableau de bord et de la liste&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;write&amp;lt;/code&amp;gt; || Déclarée pour la configuration, mais non vérifiée dans le code aujourd'hui&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;reconcile&amp;lt;/code&amp;gt; || Déclenchement manuel de la synchronisation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
En pratique, &amp;lt;code&amp;gt;admin/setup.php&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;import.php&amp;lt;/code&amp;gt; ne contrôlent que le statut '''administrateur Dolibarr''', pas le droit &amp;lt;code&amp;gt;write&amp;lt;/code&amp;gt; : seuls les administrateurs peuvent configurer le module ou importer un CSV, quoi qu'il soit coché dans les permissions.&lt;br /&gt;
&lt;br /&gt;
== 11. Base de données ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;llx_stripeaccounting_transaction&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Une ligne par objet Stripe traité — charge, frais, remboursement, litige ou virement — tous dans la même table, distingués par la colonne &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:24%;&amp;quot; | Colonne !! style=&amp;quot;width:16%;&amp;quot; | Type !! Rôle&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rowid&amp;lt;/code&amp;gt; || int AI || Clé primaire&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;entity&amp;lt;/code&amp;gt; || int || Multi-société Dolibarr&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_object_id&amp;lt;/code&amp;gt; || varchar(80) || Identifiant Stripe — '''ancre d'idempotence'''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_event_id&amp;lt;/code&amp;gt; || varchar(80) || Identifiant d'évènement, informatif seulement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt; || varchar(20) || &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;refund&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;dispute&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;other&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_source_id&amp;lt;/code&amp;gt; || varchar(80) || Objet Stripe source (ex. la charge liée à un remboursement)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;source_label&amp;lt;/code&amp;gt; || varchar(80) || Libellé libre saisi à l'import CSV ; vide pour les lignes venues de l'API&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;description&amp;lt;/code&amp;gt; || varchar(255) || Libellé Stripe&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;amount&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;net&amp;lt;/code&amp;gt; || decimal(24,8) || Montants déjà convertis depuis les centimes Stripe&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;currency&amp;lt;/code&amp;gt; || varchar(3) || Code devise ISO&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;date_created&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;date_available_on&amp;lt;/code&amp;gt; || datetime || Dates côté Stripe&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_facture&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fk_paiement&amp;lt;/code&amp;gt; || int || Facture et paiement Dolibarr résolus, si trouvés&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; || int || Ligne &amp;lt;code&amp;gt;llx_bank&amp;lt;/code&amp;gt; générée ''(vide pour un frais en mode TVA &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt;)''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;piece_num&amp;lt;/code&amp;gt; || varchar(20) || Numéro de pièce comptable généré, quand il y en a un&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt; || varchar(16) || &amp;lt;code&amp;gt;pending&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ignored&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;error_message&amp;lt;/code&amp;gt; || text || Détail en cas d'erreur&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;date_creation&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;date_processed&amp;lt;/code&amp;gt; || datetime || Horodatage technique&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_user_creat&amp;lt;/code&amp;gt; || int || Utilisateur ayant déclenché le traitement&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Clé unique''' sur &amp;lt;code&amp;gt;(stripe_object_id, entity)&amp;lt;/code&amp;gt; — c'est elle qui garantit qu'un même objet Stripe ne peut jamais être inséré deux fois, même en cas d'exécutions concurrentes.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;llx_stripeaccounting_log&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Colonne !! Rôle&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;level&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;DEBUG&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;INFO&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;WARNING&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;message&amp;lt;/code&amp;gt; || Message court&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;context&amp;lt;/code&amp;gt; || Contexte structuré en JSON&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_stripeaccounting_transaction&amp;lt;/code&amp;gt; || Transaction liée, si applicable&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;datec&amp;lt;/code&amp;gt; || Horodatage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 12. Dépannage ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:26%;&amp;quot; | Symptôme !! Cause probable !! Action&lt;br /&gt;
|-&lt;br /&gt;
| Le bouton « Synchroniser maintenant » est désactivé || Configuration minimale incomplète || Compléter les champs listés dans le bandeau d'alerte de la page de configuration&lt;br /&gt;
|-&lt;br /&gt;
| Une transaction reste en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; || Écriture refusée par Dolibarr (compte inexistant, période clôturée), ou remboursement non rattaché || Lire &amp;lt;code&amp;gt;error_message&amp;lt;/code&amp;gt; sur la ligne, puis le détail dans la table de logs&lt;br /&gt;
|-&lt;br /&gt;
| Le solde Stripe ne s'affiche pas || Clé API manquante ou invalide dans le module Stripe officiel || Vérifier &amp;lt;code&amp;gt;stripe/admin/stripe.php&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Un remboursement n'est jamais rapproché || Le paiement d'origine n'a pas été retrouvé via &amp;lt;code&amp;gt;ext_payment_id&amp;lt;/code&amp;gt; || Vérifier que le paiement Stripe a bien été enregistré par le module officiel avec cet identifiant&lt;br /&gt;
|-&lt;br /&gt;
| Un &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt; reste en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; || Tiers fournisseur Stripe non renseigné, ou sans code comptable fournisseur || Renseigner le champ en configuration, et compléter la fiche du tiers&lt;br /&gt;
|-&lt;br /&gt;
| Un remboursement importé en CSV reste en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; || '''Normal et attendu''' — ce compte n'est pas relié à &amp;lt;code&amp;gt;ext_payment_id&amp;lt;/code&amp;gt; || Traiter la facture et le remboursement manuellement en comptabilité&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 13. Pièges rencontrés ==&lt;br /&gt;
&lt;br /&gt;
Notes de développement, conservées pour éviter de retomber dedans.&lt;br /&gt;
&lt;br /&gt;
* '''&amp;lt;code&amp;gt;PaymentVarious::create()&amp;lt;/code&amp;gt;''' ne met à jour &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; qu'en base, jamais sur l'objet PHP. Un &amp;lt;code&amp;gt;fetch()&amp;lt;/code&amp;gt; après &amp;lt;code&amp;gt;create()&amp;lt;/code&amp;gt; est indispensable pour récupérer la vraie valeur.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;select_comptes()&amp;lt;/code&amp;gt;''' affiche son propre HTML ''et'' retourne le nombre de comptes. L'appeler en instruction nue : l'envelopper dans &amp;lt;code&amp;gt;print&amp;lt;/code&amp;gt; réafficherait ce nombre juste après la balise select.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;master.inc.php&amp;lt;/code&amp;gt;, pas &amp;lt;code&amp;gt;main.inc.php&amp;lt;/code&amp;gt;''' pour le script CLI. Le second attend une session HTTP et, en pur CLI, se termine silencieusement — aucune sortie, aucun log, code retour 0 — dans sa redirection vers la page de connexion. L'impression trompeuse que le script « ne fait rien » plutôt qu'une vraie erreur.&lt;br /&gt;
* '''Bibliothèques du cœur''' — &amp;lt;code&amp;gt;master.inc.php&amp;lt;/code&amp;gt; ne charge pas tout ce que &amp;lt;code&amp;gt;main.inc.php&amp;lt;/code&amp;gt; charge pour le web (par exemple &amp;lt;code&amp;gt;core/lib/date.lib.php&amp;lt;/code&amp;gt;, requis par &amp;lt;code&amp;gt;BookKeeping&amp;lt;/code&amp;gt;). À inclure explicitement si le script CLI évolue.&lt;br /&gt;
* '''Option « rien sélectionné » à &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;''' dans les sélecteurs de compte comptable — voir la section Configuration.&lt;br /&gt;
&lt;br /&gt;
== 14. Limites connues ==&lt;br /&gt;
&lt;br /&gt;
* '''Devises « zéro décimale »''' (JPY, KRW…) non gérées : les montants sont divisés par 100 en supposant deux décimales. Usage prévu : EUR.&lt;br /&gt;
* '''Fenêtre de 35 jours''' non configurable. Une synchronisation interrompue plus longtemps devra être rattrapée manuellement.&lt;br /&gt;
* '''Rattachement des remboursements''' — dépend de &amp;lt;code&amp;gt;ext_payment_id&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;ext_payment_site&amp;lt;/code&amp;gt; sur &amp;lt;code&amp;gt;llx_paiement&amp;lt;/code&amp;gt;, renseignés par le flux de paiement Stripe standard. Un paiement enregistré autrement ne pourra pas être rattaché automatiquement. Le rattachement se fait via le '''PaymentIntent id''', jamais via l'id de charge : le module Stripe du cœur ne stocke jamais ce dernier ''(il y met soit le PaymentIntent brut, soit un composite, selon le chemin de paiement emprunté)''.&lt;br /&gt;
* '''Import CSV en notation française''' uniquement : un export à point décimal ne serait pas interprété correctement.&lt;br /&gt;
* '''Colonne « Transfer » du CSV Paiements''' stockée à titre informatif seulement : elle ne sert pas à vérifier que le total des paiements correspond au montant du virement importé.&lt;br /&gt;
* '''Remboursements importés en CSV toujours en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;''' — comportement voulu, pas un bug.&lt;br /&gt;
* '''Mode TVA &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt;''' — le solde bancaire du compte Stripe ne reflète pas les frais, voir section 5.&lt;br /&gt;
&lt;br /&gt;
[[Catégorie:Dolibarr]]&lt;br /&gt;
[[Catégorie:Modules]]&lt;br /&gt;
[[Catégorie:Comptabilité]]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Stripeaccounting&amp;diff=537</id>
		<title>Stripeaccounting</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Stripeaccounting&amp;diff=537"/>
				<updated>2026-08-02T05:52:47Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : /* Réglage Dolibarr indispensable */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:StripeAccounting — Documentation technique}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border:1px solid #c8ccd1; background:#f8f9fa; border-radius:4px; padding:1em 1.2em; margin:0 0 1.5em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''StripeAccounting''' est un module Dolibarr de '''rapprochement comptable Stripe'''.&lt;br /&gt;
&lt;br /&gt;
Il lit l'API Stripe (ou un export CSV), repère les mouvements que le module Stripe officiel ne comptabilise pas — frais, remboursements, litiges, virements — et pose les écritures manquantes.&lt;br /&gt;
&lt;br /&gt;
: '''Compatibilité''' — Dolibarr 17+, PHP 7.2 → 8.5&lt;br /&gt;
: '''Dépend de''' — modules Stripe, Banque, Comptabilité en partie double&lt;br /&gt;
: '''Voir aussi''' — [[README-fr|Installation et guide utilisateur]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== 1. Principes de fonctionnement ==&lt;br /&gt;
&lt;br /&gt;
Quatre règles gouvernent tout le module.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:22%;&amp;quot; | Principe !! Ce que ça veut dire&lt;br /&gt;
|-&lt;br /&gt;
| '''Complémentaire''' || Le module ne crée aucun paiement, aucune facture, aucun webhook. Il lit Stripe et complète la comptabilité, rien de plus.&lt;br /&gt;
|-&lt;br /&gt;
| '''Idempotent''' || Chaque objet Stripe n'est traité qu'une fois, quel que soit le nombre de relances de la synchronisation.&lt;br /&gt;
|-&lt;br /&gt;
| '''Jamais de devinette''' || Si une opération ne peut pas être rattachée avec certitude, rien n'est posté : la ligne passe en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; pour revue manuelle.&lt;br /&gt;
|-&lt;br /&gt;
| '''Configuration bloquante''' || Tant que la configuration minimale est incomplète, aucune synchronisation ne démarre (ni bouton, ni cron, ni import).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2. Prérequis ==&lt;br /&gt;
&lt;br /&gt;
=== Modules Dolibarr requis ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Module !! Ce qu'il apporte&lt;br /&gt;
|-&lt;br /&gt;
| '''Stripe''' (&amp;lt;code&amp;gt;modStripe&amp;lt;/code&amp;gt;) || Clé API, mode test/live, compte financier Stripe&lt;br /&gt;
|-&lt;br /&gt;
| '''Banque''' (&amp;lt;code&amp;gt;modBanque&amp;lt;/code&amp;gt;) || Tables &amp;lt;code&amp;gt;llx_bank&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;llx_bank_account&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| '''Comptabilité en partie double''' (&amp;lt;code&amp;gt;modAccounting&amp;lt;/code&amp;gt;) || Table &amp;lt;code&amp;gt;llx_accounting_bookkeeping&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Réglage Dolibarr indispensable ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ACCOUNTING_ACCOUNT_TRANSFER_CASH&amp;lt;/code&amp;gt; doit être renseigné dans '''Comptabilité → Configuration → Comptes par défaut'''. Sans lui, le virement interne généré par les payouts ne peut pas être transféré en comptabilité (limite de Dolibarr, pas du module).&lt;br /&gt;
&lt;br /&gt;
=== Notes ===&lt;br /&gt;
&lt;br /&gt;
* Le SDK PHP Stripe n'est pas dupliqué : le module réutilise la copie du cœur (&amp;lt;code&amp;gt;includes/stripe/stripe-php/&amp;lt;/code&amp;gt;).&lt;br /&gt;
* Le code évite volontairement toute syntaxe PHP postérieure à 7.2 (pas de &amp;lt;code&amp;gt;match&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;?-&amp;gt;&amp;lt;/code&amp;gt;, enums, propriétés typées, &amp;lt;code&amp;gt;str_contains&amp;lt;/code&amp;gt;…) pour couvrir toute la plage 7.2 → 8.5.&lt;br /&gt;
&lt;br /&gt;
== 3. Arborescence ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
custom/stripeaccounting/&lt;br /&gt;
├── core/modules/modStripeAccounting.class.php   Descripteur (droits, menus, cron, constantes)&lt;br /&gt;
├── class/&lt;br /&gt;
│   ├── StripeApi.class.php                      Wrapper SDK Stripe (lecture seule)&lt;br /&gt;
│   ├── StripeRepository.class.php               Accès SQL + idempotence&lt;br /&gt;
│   ├── StripeLogger.class.php                   Journalisation&lt;br /&gt;
│   ├── StripeAccounting.class.php               Génération des écritures&lt;br /&gt;
│   ├── StripePayout.class.php                   Rapprochement des virements&lt;br /&gt;
│   ├── StripeSync.class.php                     Orchestrateur (point d'entrée du cron)&lt;br /&gt;
│   ├── StripeCsvImporter.class.php              Import CSV&lt;br /&gt;
│   └── actions_stripeaccounting.class.php       Hook 'bankcard'&lt;br /&gt;
├── admin/setup.php                              Configuration&lt;br /&gt;
├── import.php                                   Import CSV&lt;br /&gt;
├── dashboard.php                                Tableau de bord&lt;br /&gt;
├── transaction_list.php                         Liste des transactions&lt;br /&gt;
├── cron/stripe_sync.php                         Point d'entrée CLI&lt;br /&gt;
├── lib/stripeaccounting.lib.php&lt;br /&gt;
├── sql/&lt;br /&gt;
├── langs/{fr_FR,en_US,es_ES,it_IT,de_DE}/&lt;br /&gt;
└── css/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sens des dépendances ===&lt;br /&gt;
&lt;br /&gt;
: pages et hook → &amp;lt;code&amp;gt;StripeSync&amp;lt;/code&amp;gt; → (&amp;lt;code&amp;gt;StripeApi&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StripeRepository&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StripeAccounting&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StripePayout&amp;lt;/code&amp;gt;) → &amp;lt;code&amp;gt;StripeLogger&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:26%;&amp;quot; | Classe !! Rôle&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeApi&amp;lt;/code&amp;gt; || Interroge le SDK Stripe (balance transactions, charges, remboursements, litiges, payouts) avec pagination automatique. Aucun accès base, aucune écriture.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeRepository&amp;lt;/code&amp;gt; || Tout le SQL des deux tables du module. &amp;lt;code&amp;gt;upsertTransaction()&amp;lt;/code&amp;gt; est le point d'idempotence.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeLogger&amp;lt;/code&amp;gt; || Écrit dans &amp;lt;code&amp;gt;llx_stripeaccounting_log&amp;lt;/code&amp;gt; et en miroir dans &amp;lt;code&amp;gt;dol_syslog()&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeAccounting&amp;lt;/code&amp;gt; || Construit les écritures (remboursement, litige, TVA autoliquidation) ou les mouvements bancaires (frais). Expose &amp;lt;code&amp;gt;checkConfig()&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripePayout&amp;lt;/code&amp;gt; || Crée le virement bancaire interne entre le compte Stripe et la banque réelle.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeSync&amp;lt;/code&amp;gt; || Orchestrateur : une méthode par flux, plus &amp;lt;code&amp;gt;reconcileStripeAccount()&amp;lt;/code&amp;gt; qui enchaîne tout.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeCsvImporter&amp;lt;/code&amp;gt; || Alimente le même pipeline depuis un export CSV Stripe.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ActionsStripeAccounting&amp;lt;/code&amp;gt; || Hook &amp;lt;code&amp;gt;bankcard&amp;lt;/code&amp;gt; : lien vers le tableau de bord sur la fiche du compte Stripe.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 4. Synchronisation et idempotence ==&lt;br /&gt;
&lt;br /&gt;
Chaque flux (&amp;lt;code&amp;gt;syncFees&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncRefunds&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncDisputes&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncPayouts&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncTransactions&amp;lt;/code&amp;gt;) suit toujours les mêmes étapes :&lt;br /&gt;
&lt;br /&gt;
# '''Vérifier la configuration''' — si elle est incomplète : log &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt;, arrêt immédiat, aucun appel API.&lt;br /&gt;
# '''Lister les objets Stripe''' sur une fenêtre glissante de '''35 jours'''.&lt;br /&gt;
# '''Filtrer''' — un objet est ignoré seulement s'il existe déjà ''et'' que son statut est &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;ignored&amp;lt;/code&amp;gt;. Une ligne en &amp;lt;code&amp;gt;pending&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; est '''retentée''' à ce run.&lt;br /&gt;
# '''Enregistrer''' en statut &amp;lt;code&amp;gt;pending&amp;lt;/code&amp;gt;, puis générer l'écriture ou le mouvement bancaire.&lt;br /&gt;
# '''Conclure''' — succès : statut &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt;. Échec : statut &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; avec le message, et '''le lot continue''' sur l'objet suivant.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #36c; background:#eaf3ff; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Reprise automatique''' — une ligne en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; redevient éligible au run suivant. Une fois la cause corrigée (par exemple un exercice comptable créé tardivement), aucune intervention manuelle n'est nécessaire.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi les doublons sont impossibles ===&lt;br /&gt;
&lt;br /&gt;
* '''Clé unique en base''' sur &amp;lt;code&amp;gt;(stripe_object_id, entity)&amp;lt;/code&amp;gt; — protège même contre deux exécutions concurrentes du cron.&lt;br /&gt;
* '''Test explicite avant traitement''' — évite jusqu'à la tentative d'écriture pour un objet déjà finalisé.&lt;br /&gt;
&lt;br /&gt;
=== Cas particuliers : &amp;lt;code&amp;gt;adjustment&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;payment_failure_refund&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Ce sont des corrections de solde effectuées par Stripe lui-même (réversion après litige, remboursement d'un paiement finalement échoué). Le module les '''enregistre''' — sinon elles resteraient invisibles — mais ne les comptabilise '''jamais''' automatiquement : le signe du montant et la cause varient trop. Elles sont créées directement en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, avec un message explicite, à traiter manuellement.&lt;br /&gt;
&lt;br /&gt;
== 5. Écritures comptables ==&lt;br /&gt;
&lt;br /&gt;
Toutes les lignes d'un même évènement partagent le triplet &amp;lt;code&amp;gt;doc_type='stripeaccounting'&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fk_doc&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;doc_ref&amp;lt;/code&amp;gt; : Dolibarr les regroupe automatiquement sous un même numéro de pièce, sans numérotation propre au module.&lt;br /&gt;
&lt;br /&gt;
=== Vue d'ensemble ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! Évènement !! Ce que fait le module !! Résultat comptable&lt;br /&gt;
|-&lt;br /&gt;
| Frais Stripe ''(TVA &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt;)'' || Mouvement bancaire &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; || Écriture 627xxx / 517xxx générée plus tard par Dolibarr&lt;br /&gt;
|-&lt;br /&gt;
| Frais Stripe ''(mode &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt;)'' || En plus : paire TVA postée immédiatement || Débit TVA déductible, crédit TVA autoliquidation ''(impact net nul)''&lt;br /&gt;
|-&lt;br /&gt;
| Frais Stripe ''(mode &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt;)'' || Écriture directe complète || Débit compte de frais HT + TVA déductible, crédit compte Stripe TTC&lt;br /&gt;
|-&lt;br /&gt;
| Frais d'abonnement / service ''(Radar, Billing, Connect…)'' || Mouvement bancaire &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; || Écriture générée plus tard par Dolibarr, sur le compte fournisseur Stripe&lt;br /&gt;
|-&lt;br /&gt;
| Virement (payout) || Virement bancaire interne entre les 2 comptes || Écriture générée plus tard par Dolibarr&lt;br /&gt;
|-&lt;br /&gt;
| Remboursement ''(facture retrouvée)'' || Écriture directe || Débit compte client 411xxx, crédit compte Stripe 517xxx&lt;br /&gt;
|-&lt;br /&gt;
| Remboursement ''(facture introuvable)'' || Rien || Statut &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, à traiter manuellement&lt;br /&gt;
|-&lt;br /&gt;
| Litige / chargeback || Écriture directe || Débit perte sur litiges 658xxx, crédit compte Stripe 517xxx ''(+ compte de frais si frais associés)''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi frais et virements ne génèrent pas d'écriture directe ===&lt;br /&gt;
&lt;br /&gt;
Le problème historique : quand une facture Stripe est transférée en comptabilité par le workflow standard de Dolibarr, le paiement est comptabilisé pour son montant '''brut''' — les frais sont ignorés à cette étape.&lt;br /&gt;
&lt;br /&gt;
Si le module postait ''en plus'' sa propre écriture ''et'' sa propre ligne bancaire, cette ligne resterait invisible pour &amp;lt;code&amp;gt;bankjournal.php&amp;lt;/code&amp;gt; — qui ne reconnaît que les lignes rattachées à &amp;lt;code&amp;gt;doc_type='bank'&amp;lt;/code&amp;gt;. Un administrateur transférant « normalement » le compte bancaire en comptabilité créait alors une '''seconde''' écriture pour le même mouvement.&lt;br /&gt;
&lt;br /&gt;
'''La solution retenue :''' pour les frais, les frais d'abonnement et les virements, le module ne crée plus que le '''mouvement bancaire réel''', avec les mécanismes natifs de Dolibarr. C'est ensuite le bouton natif ''« Transférer en comptabilité »'' qui produit l'écriture, comme pour n'importe quel autre mouvement bancaire. Le module ne touche donc plus du tout &amp;lt;code&amp;gt;llx_accounting_bookkeeping&amp;lt;/code&amp;gt; dans ces trois cas.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:22%;&amp;quot; | Cas !! Mécanisme natif utilisé&lt;br /&gt;
|-&lt;br /&gt;
| Frais et frais d'abonnement || &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; (mouvement bancaire avec compte de contrepartie, sans tiers ni facture), avec son propre &amp;lt;code&amp;gt;accountancy_code&amp;lt;/code&amp;gt; que &amp;lt;code&amp;gt;bankjournal.php&amp;lt;/code&amp;gt; lit directement.&lt;br /&gt;
|-&lt;br /&gt;
| Virements (payouts) || Virement interne Dolibarr : &amp;lt;code&amp;gt;Account::addline()&amp;lt;/code&amp;gt; des deux côtés, plus &amp;lt;code&amp;gt;add_url_line(…, 'banktransfert')&amp;lt;/code&amp;gt;. La contrepartie est imputée sur &amp;lt;code&amp;gt;ACCOUNTING_ACCOUNT_TRANSFER_CASH&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Dans les deux cas, le statut passe à &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt; — le module a fini son travail — mais '''&amp;lt;code&amp;gt;piece_num&amp;lt;/code&amp;gt; reste vide''' : l'écriture n'existe pas encore, seul &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; est renseigné. Après transfert manuel, on la retrouve avec &amp;lt;code&amp;gt;doc_type='bank'&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;fk_doc&amp;lt;/code&amp;gt; égal au &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; de la ligne.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #fc3; background:#fef6e7; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''À savoir''' — l'écriture des virements ne s'équilibre à zéro sur le compte de transfert que lorsque '''les deux''' comptes bancaires (Stripe ''et'' la banque réelle) ont été transférés en comptabilité, pas seulement un des deux.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #d33; background:#fee7e6; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''⚠ &amp;lt;code&amp;gt;STRIPE_AUTO_RECORD_PAYOUT&amp;lt;/code&amp;gt; doit rester désactivé'''&lt;br /&gt;
&lt;br /&gt;
Dès lors que ce module gère les virements, décochez « Activer l'enregistrement automatique des paiements Stripe » dans &amp;lt;code&amp;gt;stripe/admin/stripe.php&amp;lt;/code&amp;gt; — malgré son libellé, cette case ne concerne que les virements.&lt;br /&gt;
&lt;br /&gt;
Sinon, le webhook du module officiel et ce module créeraient chacun leur propre mouvement bancaire pour le même virement, sans le savoir l'un de l'autre.&lt;br /&gt;
&lt;br /&gt;
Le webhook cœur ne conserve d'ailleurs '''aucune''' trace de l'id du virement traité : en cas de double livraison Stripe (garantie « au moins une fois »), rien ne l'empêche de doublonner tout seul. Ce module, lui, a une vraie idempotence et rattrape automatiquement tout virement manqué sur 35 jours.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Page « Transferts Stripe » masquée ===&lt;br /&gt;
&lt;br /&gt;
À l'activation, &amp;lt;code&amp;gt;modStripeAccounting::init()&amp;lt;/code&amp;gt; désactive l'entrée de menu &amp;lt;code&amp;gt;stripe/payout.php&amp;lt;/code&amp;gt; : cette page interroge l'API en direct sans rien enregistrer, et sa coexistence avec ce module ne créerait qu'une confusion sur ce qui fait foi pour les virements. &amp;lt;code&amp;gt;remove()&amp;lt;/code&amp;gt; restaure la condition d'origine. '''C'est la seule table du cœur que ce module modifie''' — délibéré, et documenté ici pour cette raison.&lt;br /&gt;
&lt;br /&gt;
=== Frais par transaction ou frais d'abonnement ? ===&lt;br /&gt;
&lt;br /&gt;
Stripe facture deux choses distinctes sous le mot « frais » :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! !! Frais par transaction !! Frais d'abonnement / service&lt;br /&gt;
|-&lt;br /&gt;
! Exemple&lt;br /&gt;
| Commission sur chaque encaissement || Radar, Billing, Connect&lt;br /&gt;
|-&lt;br /&gt;
! Où le trouver&lt;br /&gt;
| Champ &amp;lt;code&amp;gt;.fee&amp;lt;/code&amp;gt; d'une balance transaction de type &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; || Balance transaction dédiée, de type &amp;lt;code&amp;gt;stripe_fee&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;application_fee&amp;lt;/code&amp;gt; ''(le &amp;lt;code&amp;gt;.fee&amp;lt;/code&amp;gt; y vaut toujours 0, le montant est dans &amp;lt;code&amp;gt;.amount&amp;lt;/code&amp;gt;)''&lt;br /&gt;
|-&lt;br /&gt;
! Compte utilisé&lt;br /&gt;
| Compte de frais configuré (627xxx) || Code comptable fournisseur du tiers Stripe configuré&lt;br /&gt;
|-&lt;br /&gt;
! Type en base&lt;br /&gt;
| &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Limite du mode TVA &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Ce mode doit scinder le montant TTC en HT + TVA, un découpage que &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; ne sait pas exprimer. Il reste donc sur l'ancien comportement : écriture directe complète, aucun mouvement bancaire créé. Pas de risque de doublon (puisque aucune ligne bancaire n'est produite), mais le solde &amp;lt;code&amp;gt;llx_bank&amp;lt;/code&amp;gt; du compte Stripe ne reflétera jamais les frais tant que ce mode est actif.&lt;br /&gt;
&lt;br /&gt;
== 6. Import CSV ==&lt;br /&gt;
&lt;br /&gt;
L'import couvre le cas d'un compte Stripe '''différent''' de celui configuré dans le module officiel — par exemple une autre boutique PrestaShop avec son propre compte marchand. L'API n'y a pas accès : le contenu est exporté en CSV depuis le dashboard Stripe, puis importé.&lt;br /&gt;
&lt;br /&gt;
=== Hypothèse de départ ===&lt;br /&gt;
&lt;br /&gt;
Les factures et paiements de cette boutique sont '''déjà''' comptabilisés dans Dolibarr par un autre processus, et l'encaissement (débit 517, crédit 411) est déjà posé. Seuls manquent les '''frais''', les '''remboursements''' et les '''virements''' — c'est exactement ce que l'import traite.&lt;br /&gt;
&lt;br /&gt;
=== Interface : un seul champ ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;import.php&amp;lt;/code&amp;gt; n'expose plus qu'un champ d'upload, '''Historique général''', câblé sur &amp;lt;code&amp;gt;importGeneralHistory()&amp;lt;/code&amp;gt;. Ce fichier couvre à lui seul tous les types de mouvements.&lt;br /&gt;
&lt;br /&gt;
Les méthodes &amp;lt;code&amp;gt;importPayments()&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;importPayouts()&amp;lt;/code&amp;gt; restent implémentées et fonctionnelles, mais ne sont plus atteignables depuis l'interface ; elles sont documentées ci-dessous pour mémoire.&lt;br /&gt;
&lt;br /&gt;
Comme le bouton « Synchroniser maintenant », l'import est bloqué — bandeau d'alerte, bouton désactivé, garde-fou côté serveur — tant que la configuration est incomplète.&lt;br /&gt;
&lt;br /&gt;
=== Les trois méthodes ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:24%;&amp;quot; | Méthode !! Export Stripe lu !! Traitement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;importGeneralHistory()&amp;lt;/code&amp;gt;&amp;lt;br /&amp;gt;''(seule exposée)'' || Balance history || Aiguillage par colonne &amp;lt;code&amp;gt;Type&amp;lt;/code&amp;gt;, voir tableau ci-dessous&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;importPayments()&amp;lt;/code&amp;gt; || Payments || Frais → écriture de frais. Montant remboursé → ligne &amp;lt;code&amp;gt;refund&amp;lt;/code&amp;gt; toujours en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;importPayouts()&amp;lt;/code&amp;gt; || Payouts || Exactement le même traitement qu'un payout venu de l'API&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Aiguillage de l'historique général, par colonne &amp;lt;code&amp;gt;Type&amp;lt;/code&amp;gt; :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:30%;&amp;quot; | Type Stripe !! Traitement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt; || Virement bancaire interne, comme via l'API&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;payment&amp;lt;/code&amp;gt; avec frais || Mouvement de frais&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_fee&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;application_fee&amp;lt;/code&amp;gt; || Frais d'abonnement, sur le compte fournisseur Stripe&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;refund&amp;lt;/code&amp;gt; || Enregistré, '''toujours''' en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;payout_minimum_balance_hold&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;…_release&amp;lt;/code&amp;gt; || '''Ignorés''' — réserve glissante Stripe, impact net nul, rien à comptabiliser&lt;br /&gt;
|-&lt;br /&gt;
| tout autre type || Enregistré en &amp;lt;code&amp;gt;type='other'&amp;lt;/code&amp;gt;, statut &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, type brut conservé dans la description. Aucune écriture devinée.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les colonnes sont reconnues '''par leur nom''' : l'ordre importe peu, et les colonnes en plus non utilisées sont ignorées.&lt;br /&gt;
&lt;br /&gt;
=== Idempotence de l'import ===&lt;br /&gt;
&lt;br /&gt;
La clé unique protège contre tout double import : réimporter le même CSV, ou un CSV qui chevauche un import précédent, ne crée aucun doublon.&lt;br /&gt;
&lt;br /&gt;
Point important : dans l'historique général, les lignes &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;payment&amp;lt;/code&amp;gt; sont indexées par leur colonne '''&amp;lt;code&amp;gt;Source&amp;lt;/code&amp;gt;''' (&amp;lt;code&amp;gt;po_…&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ch_…&amp;lt;/code&amp;gt;), pas par l'&amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt; de la ligne (&amp;lt;code&amp;gt;txn_…&amp;lt;/code&amp;gt;) — soit exactement la même clé que les imports dédiés. Importer l'historique général '''en plus''' des exports spécifiques ne poste donc jamais deux fois la même écriture, quel que soit l'ordre.&lt;br /&gt;
&lt;br /&gt;
Les identifiants Stripe étant uniques à l'échelle de la plateforme, mélanger dans la même table des lignes venant du compte API et de plusieurs comptes importés en CSV ne présente aucun risque de collision.&lt;br /&gt;
&lt;br /&gt;
=== Détails pratiques ===&lt;br /&gt;
&lt;br /&gt;
* '''Libellé source''' — un champ libre saisi à l'import (ex. « Boutique DRM ») est stocké sur chaque ligne créée et sert de colonne et de filtre dans la liste, pour distinguer plusieurs boutiques côte à côte.&lt;br /&gt;
* '''Format des montants''' — les CSV Stripe utilisent la virgule décimale française, convertie via &amp;lt;code&amp;gt;price2num()&amp;lt;/code&amp;gt;. Les dates marquées &amp;lt;code&amp;gt;(UTC)&amp;lt;/code&amp;gt; sont interprétées comme telles.&lt;br /&gt;
&lt;br /&gt;
== 7. Configuration ==&lt;br /&gt;
&lt;br /&gt;
La clé API et le mode test/live ne sont '''pas''' ressaisis ici : ils sont lus en lecture seule depuis le module Stripe officiel.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:26%;&amp;quot; | Champ !! Constante !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| Compte financier Stripe || &amp;lt;code&amp;gt;STRIPE_BANK_ACCOUNT_FOR_PAYMENTS&amp;lt;/code&amp;gt; ''(constante du module officiel)'' || Sélecteur de compte bancaire. Aucune copie locale, donc aucun risque de divergence.&lt;br /&gt;
|-&lt;br /&gt;
| Compte bancaire principal || &amp;lt;code&amp;gt;STRIPE_BANK_ACCOUNT_FOR_BANKTRANSFERS&amp;lt;/code&amp;gt; ''(constante du module officiel)'' || Même sélecteur. Voir l'encadré ci-dessous.&lt;br /&gt;
|-&lt;br /&gt;
| Compte de frais || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_FRAIS&amp;lt;/code&amp;gt; || Numéro de compte, ex. 627xxx&lt;br /&gt;
|-&lt;br /&gt;
| Compte de litiges || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_LITIGES&amp;lt;/code&amp;gt; || Numéro de compte, ex. 658xxx. '''Requis''' — utilisé dès qu'un litige survient, quel que soit le mode TVA.&lt;br /&gt;
|-&lt;br /&gt;
| Tiers fournisseur Stripe || &amp;lt;code&amp;gt;STRIPEACCOUNTING_FOURNISSEUR_STRIPE_ID&amp;lt;/code&amp;gt; || Tiers marqué fournisseur ; c'est son code comptable fournisseur qui est utilisé. Optionnel, sauf s'il existe des frais d'abonnement.&lt;br /&gt;
|-&lt;br /&gt;
| Mode TVA || &amp;lt;code&amp;gt;STRIPEACCOUNTING_VAT_MODE&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Compte TVA déductible (intracommunautaire) || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_TVA_DEDUCTIBLE&amp;lt;/code&amp;gt; || Requis si mode TVA ≠ &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt;. Stripe facturant toujours depuis une entité UE non française, la TVA déductible est intracommunautaire dans tous les cas.&lt;br /&gt;
|-&lt;br /&gt;
| Compte de TVA due (intracommunautaire) || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_TVA_AUTOLIQUIDATION&amp;lt;/code&amp;gt; || Requis en mode &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt; uniquement — jamais utilisé en mode &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| Taux de TVA || &amp;lt;code&amp;gt;STRIPEACCOUNTING_VAT_RATE&amp;lt;/code&amp;gt; || Pourcentage, 20 par défaut&lt;br /&gt;
|-&lt;br /&gt;
| Fréquence de synchronisation || &amp;lt;code&amp;gt;STRIPEACCOUNTING_SYNC_UNITFREQUENCY&amp;lt;/code&amp;gt; || Répercutée sur la tâche planifiée (en secondes)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #36c; background:#eaf3ff; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Pourquoi redéfinir le compte bancaire principal ici ?'''&lt;br /&gt;
&lt;br /&gt;
La page de configuration du module Stripe officiel n'affiche ce champ que si &amp;lt;code&amp;gt;STRIPE_AUTO_RECORD_PAYOUT&amp;lt;/code&amp;gt; est activé — et son handler de sauvegarde remet la valeur à 0 à chaque enregistrement tant que le champ n'est pas rendu. Or ce réglage doit justement rester désactivé quand ce module gère les virements. Le champ est donc réexposé ici, en écrivant directement la constante du cœur, pour que la valeur reste configurable et stable.&lt;br /&gt;
&lt;br /&gt;
Les deux sélecteurs de compte n'écrivent leur constante que si un compte réel a été soumis : enregistrer la page pour un tout autre champ n'écrase jamais une valeur correcte.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Vérification de la configuration ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;StripeAccounting::checkConfig()&amp;lt;/code&amp;gt; renvoie la liste des constantes manquantes. Elle est appelée à la fois par la page de configuration (bandeau d'information) et par chaque point d'entrée de synchronisation (garde-fou réel qui bloque tout traitement).&lt;br /&gt;
&lt;br /&gt;
=== Piège des sélecteurs de compte comptable ===&lt;br /&gt;
&lt;br /&gt;
Les quatre champs utilisant &amp;lt;code&amp;gt;FormAccounting::select_account()&amp;lt;/code&amp;gt; (frais, litiges, les deux comptes TVA) ont une option « rien sélectionné » dont la valeur est '''&amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;''' — une chaîne non vide, donc vraie en PHP. Un champ laissé vide et enregistré stocke littéralement &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;StripeAccounting::getAccountConst()&amp;lt;/code&amp;gt; normalise cette valeur en chaîne vide à la lecture, partout où ces constantes sont lues. Aucune écriture ne peut donc atterrir sur le compte inexistant &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 8. Interface ==&lt;br /&gt;
&lt;br /&gt;
=== Tableau de bord ===&lt;br /&gt;
&lt;br /&gt;
Solde Stripe (appel API en direct), nombre de transactions non rapprochées, total des frais du mois, payouts en attente, et bouton '''Synchroniser maintenant''' — désactivé, avec bandeau listant les constantes manquantes, tant que la configuration est incomplète.&lt;br /&gt;
&lt;br /&gt;
=== Liste des transactions ===&lt;br /&gt;
&lt;br /&gt;
Liste paginée, triable et filtrable, construite avec le même mécanisme que les listes natives Dolibarr : l'icône en haut à droite du tableau permet à chaque utilisateur de choisir ses colonnes, et la préférence est mémorisée par utilisateur.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:20%;&amp;quot; | Colonne !! Contenu&lt;br /&gt;
|-&lt;br /&gt;
| Montant, Frais, Total || Le popup sur les frais indique la TVA sur frais quand une paire d'autoliquidation ou une TVA française a été postée&lt;br /&gt;
|-&lt;br /&gt;
| Type, Description || Popup avec l'ID Stripe, l'ID d'évènement ou de source, et la description complète non tronquée&lt;br /&gt;
|-&lt;br /&gt;
| Tiers || Le client résolu via la facture, ou via la charge source pour son frais associé, ou le tiers fournisseur Stripe pour un frais d'abonnement&lt;br /&gt;
|-&lt;br /&gt;
| Écriture || Lien « Pièce n°X » vers l'écriture, et/ou lien vers le mouvement bancaire associé — voir la nuance ci-dessous&lt;br /&gt;
|-&lt;br /&gt;
| Source, Statut || Le badge &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; ouvre un popup avec le message d'erreur complet : plus besoin d'aller en base pour comprendre un échec&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #fc3; background:#fef6e7; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Lire la colonne « Écriture »''' — sur une ligne &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt;, le lien pointe vers le '''mouvement bancaire''', pas vers une pièce comptable. Le &amp;lt;code&amp;gt;piece_num&amp;lt;/code&amp;gt; du module, lui, n'est jamais l'écriture 627/517 du frais : c'est uniquement la paire TVA d'autoliquidation. L'écriture du frais est générée plus tard, par le bouton natif de Dolibarr, et n'est jamais reportée sur cette ligne.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La page est '''purement consultative''' : aucune comptabilisation manuelle n'y est proposée. Le module comptabilise automatiquement, et le transfert en comptabilité des frais et virements se fait depuis le bouton natif « Transférer en comptabilité ».&lt;br /&gt;
&lt;br /&gt;
=== Lignes &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Chaque paiement produit '''deux lignes''' en base :&lt;br /&gt;
&lt;br /&gt;
* une ligne &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt;, toujours en statut &amp;lt;code&amp;gt;ignored&amp;lt;/code&amp;gt;, frais à 0, jamais traitée — présente uniquement pour l'idempotence ;&lt;br /&gt;
* une ligne &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; pour le même paiement, liée à la première.&lt;br /&gt;
&lt;br /&gt;
Les deux apparaissent séparément dans la liste, mais la ligne &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; porte elle aussi le lien vers le paiement et la facture, résolu par jointure.&lt;br /&gt;
&lt;br /&gt;
=== Bandeau mode test ===&lt;br /&gt;
&lt;br /&gt;
Tant que le mode live n'est pas activé, le tableau de bord, la page de configuration et la liste des transactions affichent tous les trois le même avertissement que le module Stripe officiel. Impossible d'oublier qu'on travaille en mode test.&lt;br /&gt;
&lt;br /&gt;
=== Menus ===&lt;br /&gt;
&lt;br /&gt;
Tout est regroupé sous '''Banques et caisses → Compte Stripe''' (menu du module officiel), à plat, en trois entrées de même niveau :&lt;br /&gt;
&lt;br /&gt;
# Tableau de bord Stripe&lt;br /&gt;
# Transactions Stripe&lt;br /&gt;
# Import CSV ''(réservé aux administrateurs)''&lt;br /&gt;
&lt;br /&gt;
Un lien vers le tableau de bord est aussi ajouté automatiquement sur la fiche du compte bancaire configuré comme compte Stripe.&lt;br /&gt;
&lt;br /&gt;
== 9. Tâche planifiée ==&lt;br /&gt;
&lt;br /&gt;
Deux façons d'exécuter la synchronisation, toutes deux idempotentes et sans risque à relancer. Dans les deux cas le code exécuté est strictement le même : aucune divergence de comportement.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #d33; background:#fee7e6; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''⚠ Aucune des deux ne démarre toute seule.'''&lt;br /&gt;
&lt;br /&gt;
L'activation du module crée la tâche &amp;lt;code&amp;gt;StripeAccountingSync&amp;lt;/code&amp;gt;, mais '''désactivée par défaut'''. Et même activée, l'ordonnanceur Dolibarr n'est déclenché par rien tant qu'aucune crontab système ne l'appelle. Sans ces deux étapes, la synchro n'a lieu qu'au clic manuel sur « Synchroniser maintenant ».&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Étape 1 — activer la tâche ===&lt;br /&gt;
&lt;br /&gt;
Dans '''Accueil → Configuration → Modules → Tâches planifiées'''. &amp;lt;code&amp;gt;llx_cronjob&amp;lt;/code&amp;gt; étant une table du cœur, ce réglage se fait uniquement par l'interface, jamais en SQL direct depuis le module.&lt;br /&gt;
&lt;br /&gt;
=== Étape 2 — un déclencheur système ===&lt;br /&gt;
&lt;br /&gt;
Au choix, l'une des deux options.&lt;br /&gt;
&lt;br /&gt;
'''Option A — ordonnanceur Dolibarr''' ''(recommandé si plusieurs tâches planifiées coexistent)''. Lance toutes les tâches dues, pas seulement celle-ci. Nécessite l'étape 1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
*/15 * * * * curl &amp;quot;https://votre-dolibarr/public/cron/cron_run_jobs_by_url.php?securitykey=VOTRE_CLE&amp;amp;userlogin=VOTRE_LOGIN&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La clé de sécurité se génère sur la page des tâches planifiées, bouton « Sécurité de l'exécution des tâches par URL ».&lt;br /&gt;
&lt;br /&gt;
'''Option B — script CLI du module.''' Autonome, refuse l'exécution depuis un navigateur, et indépendant de l'état activé ou non de la tâche Dolibarr.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
*/15 * * * * php /chemin/vers/htdocs/custom/stripeaccounting/cron/stripe_sync.php &amp;gt;&amp;gt; /var/log/stripeaccounting.log 2&amp;gt;&amp;amp;1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 10. Journalisation et permissions ==&lt;br /&gt;
&lt;br /&gt;
=== Journalisation ===&lt;br /&gt;
&lt;br /&gt;
Chaque appel API, écriture générée, avertissement ou erreur est tracé dans &amp;lt;code&amp;gt;llx_stripeaccounting_log&amp;lt;/code&amp;gt;, consultable en base ou via le fichier de log standard Dolibarr. Niveaux : &amp;lt;code&amp;gt;DEBUG&amp;lt;/code&amp;gt; &amp;lt; &amp;lt;code&amp;gt;INFO&amp;lt;/code&amp;gt; &amp;lt; &amp;lt;code&amp;gt;WARNING&amp;lt;/code&amp;gt; &amp;lt; &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt;. La colonne &amp;lt;code&amp;gt;context&amp;lt;/code&amp;gt; contient le détail structuré en JSON (payload API, montants calculés…).&lt;br /&gt;
&lt;br /&gt;
=== Permissions ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Droit !! Contrôle&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;read&amp;lt;/code&amp;gt; || Consultation du tableau de bord et de la liste&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;write&amp;lt;/code&amp;gt; || Déclarée pour la configuration, mais non vérifiée dans le code aujourd'hui&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;reconcile&amp;lt;/code&amp;gt; || Déclenchement manuel de la synchronisation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
En pratique, &amp;lt;code&amp;gt;admin/setup.php&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;import.php&amp;lt;/code&amp;gt; ne contrôlent que le statut '''administrateur Dolibarr''', pas le droit &amp;lt;code&amp;gt;write&amp;lt;/code&amp;gt; : seuls les administrateurs peuvent configurer le module ou importer un CSV, quoi qu'il soit coché dans les permissions.&lt;br /&gt;
&lt;br /&gt;
== 11. Base de données ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;llx_stripeaccounting_transaction&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Une ligne par objet Stripe traité — charge, frais, remboursement, litige ou virement — tous dans la même table, distingués par la colonne &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:24%;&amp;quot; | Colonne !! style=&amp;quot;width:16%;&amp;quot; | Type !! Rôle&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rowid&amp;lt;/code&amp;gt; || int AI || Clé primaire&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;entity&amp;lt;/code&amp;gt; || int || Multi-société Dolibarr&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_object_id&amp;lt;/code&amp;gt; || varchar(80) || Identifiant Stripe — '''ancre d'idempotence'''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_event_id&amp;lt;/code&amp;gt; || varchar(80) || Identifiant d'évènement, informatif seulement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt; || varchar(20) || &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;refund&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;dispute&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;other&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_source_id&amp;lt;/code&amp;gt; || varchar(80) || Objet Stripe source (ex. la charge liée à un remboursement)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;source_label&amp;lt;/code&amp;gt; || varchar(80) || Libellé libre saisi à l'import CSV ; vide pour les lignes venues de l'API&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;description&amp;lt;/code&amp;gt; || varchar(255) || Libellé Stripe&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;amount&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;net&amp;lt;/code&amp;gt; || decimal(24,8) || Montants déjà convertis depuis les centimes Stripe&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;currency&amp;lt;/code&amp;gt; || varchar(3) || Code devise ISO&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;date_created&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;date_available_on&amp;lt;/code&amp;gt; || datetime || Dates côté Stripe&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_facture&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fk_paiement&amp;lt;/code&amp;gt; || int || Facture et paiement Dolibarr résolus, si trouvés&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; || int || Ligne &amp;lt;code&amp;gt;llx_bank&amp;lt;/code&amp;gt; générée ''(vide pour un frais en mode TVA &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt;)''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;piece_num&amp;lt;/code&amp;gt; || varchar(20) || Numéro de pièce comptable généré, quand il y en a un&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt; || varchar(16) || &amp;lt;code&amp;gt;pending&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ignored&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;error_message&amp;lt;/code&amp;gt; || text || Détail en cas d'erreur&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;date_creation&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;date_processed&amp;lt;/code&amp;gt; || datetime || Horodatage technique&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_user_creat&amp;lt;/code&amp;gt; || int || Utilisateur ayant déclenché le traitement&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Clé unique''' sur &amp;lt;code&amp;gt;(stripe_object_id, entity)&amp;lt;/code&amp;gt; — c'est elle qui garantit qu'un même objet Stripe ne peut jamais être inséré deux fois, même en cas d'exécutions concurrentes.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;llx_stripeaccounting_log&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Colonne !! Rôle&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;level&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;DEBUG&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;INFO&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;WARNING&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;message&amp;lt;/code&amp;gt; || Message court&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;context&amp;lt;/code&amp;gt; || Contexte structuré en JSON&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_stripeaccounting_transaction&amp;lt;/code&amp;gt; || Transaction liée, si applicable&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;datec&amp;lt;/code&amp;gt; || Horodatage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 12. Dépannage ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:26%;&amp;quot; | Symptôme !! Cause probable !! Action&lt;br /&gt;
|-&lt;br /&gt;
| Le bouton « Synchroniser maintenant » est désactivé || Configuration minimale incomplète || Compléter les champs listés dans le bandeau d'alerte de la page de configuration&lt;br /&gt;
|-&lt;br /&gt;
| Une transaction reste en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; || Écriture refusée par Dolibarr (compte inexistant, période clôturée), ou remboursement non rattaché || Lire &amp;lt;code&amp;gt;error_message&amp;lt;/code&amp;gt; sur la ligne, puis le détail dans la table de logs&lt;br /&gt;
|-&lt;br /&gt;
| Le solde Stripe ne s'affiche pas || Clé API manquante ou invalide dans le module Stripe officiel || Vérifier &amp;lt;code&amp;gt;stripe/admin/stripe.php&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Un remboursement n'est jamais rapproché || Le paiement d'origine n'a pas été retrouvé via &amp;lt;code&amp;gt;ext_payment_id&amp;lt;/code&amp;gt; || Vérifier que le paiement Stripe a bien été enregistré par le module officiel avec cet identifiant&lt;br /&gt;
|-&lt;br /&gt;
| Un &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt; reste en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; || Tiers fournisseur Stripe non renseigné, ou sans code comptable fournisseur || Renseigner le champ en configuration, et compléter la fiche du tiers&lt;br /&gt;
|-&lt;br /&gt;
| Un remboursement importé en CSV reste en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; || '''Normal et attendu''' — ce compte n'est pas relié à &amp;lt;code&amp;gt;ext_payment_id&amp;lt;/code&amp;gt; || Traiter la facture et le remboursement manuellement en comptabilité&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 13. Pièges rencontrés ==&lt;br /&gt;
&lt;br /&gt;
Notes de développement, conservées pour éviter de retomber dedans.&lt;br /&gt;
&lt;br /&gt;
* '''&amp;lt;code&amp;gt;PaymentVarious::create()&amp;lt;/code&amp;gt;''' ne met à jour &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; qu'en base, jamais sur l'objet PHP. Un &amp;lt;code&amp;gt;fetch()&amp;lt;/code&amp;gt; après &amp;lt;code&amp;gt;create()&amp;lt;/code&amp;gt; est indispensable pour récupérer la vraie valeur.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;select_comptes()&amp;lt;/code&amp;gt;''' affiche son propre HTML ''et'' retourne le nombre de comptes. L'appeler en instruction nue : l'envelopper dans &amp;lt;code&amp;gt;print&amp;lt;/code&amp;gt; réafficherait ce nombre juste après la balise select.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;master.inc.php&amp;lt;/code&amp;gt;, pas &amp;lt;code&amp;gt;main.inc.php&amp;lt;/code&amp;gt;''' pour le script CLI. Le second attend une session HTTP et, en pur CLI, se termine silencieusement — aucune sortie, aucun log, code retour 0 — dans sa redirection vers la page de connexion. L'impression trompeuse que le script « ne fait rien » plutôt qu'une vraie erreur.&lt;br /&gt;
* '''Bibliothèques du cœur''' — &amp;lt;code&amp;gt;master.inc.php&amp;lt;/code&amp;gt; ne charge pas tout ce que &amp;lt;code&amp;gt;main.inc.php&amp;lt;/code&amp;gt; charge pour le web (par exemple &amp;lt;code&amp;gt;core/lib/date.lib.php&amp;lt;/code&amp;gt;, requis par &amp;lt;code&amp;gt;BookKeeping&amp;lt;/code&amp;gt;). À inclure explicitement si le script CLI évolue.&lt;br /&gt;
* '''Option « rien sélectionné » à &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;''' dans les sélecteurs de compte comptable — voir la section Configuration.&lt;br /&gt;
&lt;br /&gt;
== 14. Limites connues ==&lt;br /&gt;
&lt;br /&gt;
* '''Devises « zéro décimale »''' (JPY, KRW…) non gérées : les montants sont divisés par 100 en supposant deux décimales. Usage prévu : EUR.&lt;br /&gt;
* '''Fenêtre de 35 jours''' non configurable. Une synchronisation interrompue plus longtemps devra être rattrapée manuellement.&lt;br /&gt;
* '''Rattachement des remboursements''' — dépend de &amp;lt;code&amp;gt;ext_payment_id&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;ext_payment_site&amp;lt;/code&amp;gt; sur &amp;lt;code&amp;gt;llx_paiement&amp;lt;/code&amp;gt;, renseignés par le flux de paiement Stripe standard. Un paiement enregistré autrement ne pourra pas être rattaché automatiquement. Le rattachement se fait via le '''PaymentIntent id''', jamais via l'id de charge : le module Stripe du cœur ne stocke jamais ce dernier ''(il y met soit le PaymentIntent brut, soit un composite, selon le chemin de paiement emprunté)''.&lt;br /&gt;
* '''Import CSV en notation française''' uniquement : un export à point décimal ne serait pas interprété correctement.&lt;br /&gt;
* '''Colonne « Transfer » du CSV Paiements''' stockée à titre informatif seulement : elle ne sert pas à vérifier que le total des paiements correspond au montant du virement importé.&lt;br /&gt;
* '''Remboursements importés en CSV toujours en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;''' — comportement voulu, pas un bug.&lt;br /&gt;
* '''Mode TVA &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt;''' — le solde bancaire du compte Stripe ne reflète pas les frais, voir section 5.&lt;br /&gt;
&lt;br /&gt;
[[Catégorie:Dolibarr]]&lt;br /&gt;
[[Catégorie:Modules]]&lt;br /&gt;
[[Catégorie:Comptabilité]]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Stripeaccounting&amp;diff=536</id>
		<title>Stripeaccounting</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Stripeaccounting&amp;diff=536"/>
				<updated>2026-08-02T05:31:58Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : Page créée avec « {{DISPLAYTITLE:StripeAccounting — Documentation technique}}  &amp;lt;div style=&amp;quot;border:1px solid #c8ccd1; background:#f8f9fa; border-radius:4px; padding:1em 1.2em; margin:0 0 1... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:StripeAccounting — Documentation technique}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border:1px solid #c8ccd1; background:#f8f9fa; border-radius:4px; padding:1em 1.2em; margin:0 0 1.5em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''StripeAccounting''' est un module Dolibarr de '''rapprochement comptable Stripe'''.&lt;br /&gt;
&lt;br /&gt;
Il lit l'API Stripe (ou un export CSV), repère les mouvements que le module Stripe officiel ne comptabilise pas — frais, remboursements, litiges, virements — et pose les écritures manquantes.&lt;br /&gt;
&lt;br /&gt;
: '''Compatibilité''' — Dolibarr 17+, PHP 7.2 → 8.5&lt;br /&gt;
: '''Dépend de''' — modules Stripe, Banque, Comptabilité en partie double&lt;br /&gt;
: '''Voir aussi''' — [[README-fr|Installation et guide utilisateur]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== 1. Principes de fonctionnement ==&lt;br /&gt;
&lt;br /&gt;
Quatre règles gouvernent tout le module.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:22%;&amp;quot; | Principe !! Ce que ça veut dire&lt;br /&gt;
|-&lt;br /&gt;
| '''Complémentaire''' || Le module ne crée aucun paiement, aucune facture, aucun webhook. Il lit Stripe et complète la comptabilité, rien de plus.&lt;br /&gt;
|-&lt;br /&gt;
| '''Idempotent''' || Chaque objet Stripe n'est traité qu'une fois, quel que soit le nombre de relances de la synchronisation.&lt;br /&gt;
|-&lt;br /&gt;
| '''Jamais de devinette''' || Si une opération ne peut pas être rattachée avec certitude, rien n'est posté : la ligne passe en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; pour revue manuelle.&lt;br /&gt;
|-&lt;br /&gt;
| '''Configuration bloquante''' || Tant que la configuration minimale est incomplète, aucune synchronisation ne démarre (ni bouton, ni cron, ni import).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2. Prérequis ==&lt;br /&gt;
&lt;br /&gt;
=== Modules Dolibarr requis ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Module !! Ce qu'il apporte&lt;br /&gt;
|-&lt;br /&gt;
| '''Stripe''' (&amp;lt;code&amp;gt;modStripe&amp;lt;/code&amp;gt;) || Clé API, mode test/live, compte financier Stripe&lt;br /&gt;
|-&lt;br /&gt;
| '''Banque''' (&amp;lt;code&amp;gt;modBanque&amp;lt;/code&amp;gt;) || Tables &amp;lt;code&amp;gt;llx_bank&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;llx_bank_account&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| '''Comptabilité en partie double''' (&amp;lt;code&amp;gt;modAccounting&amp;lt;/code&amp;gt;) || Table &amp;lt;code&amp;gt;llx_accounting_bookkeeping&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Réglage Dolibarr indispensable ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ACCOUNTING_ACCOUNT_TRANSFER_CASH&amp;lt;/code&amp;gt; doit être renseigné dans '''Comptabilité → Configuration → Comptes divers'''. Sans lui, le virement interne généré par les payouts ne peut pas être transféré en comptabilité (limite de Dolibarr, pas du module).&lt;br /&gt;
&lt;br /&gt;
=== Notes ===&lt;br /&gt;
&lt;br /&gt;
* Le SDK PHP Stripe n'est pas dupliqué : le module réutilise la copie du cœur (&amp;lt;code&amp;gt;includes/stripe/stripe-php/&amp;lt;/code&amp;gt;).&lt;br /&gt;
* Le code évite volontairement toute syntaxe PHP postérieure à 7.2 (pas de &amp;lt;code&amp;gt;match&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;?-&amp;gt;&amp;lt;/code&amp;gt;, enums, propriétés typées, &amp;lt;code&amp;gt;str_contains&amp;lt;/code&amp;gt;…) pour couvrir toute la plage 7.2 → 8.5.&lt;br /&gt;
&lt;br /&gt;
== 3. Arborescence ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
custom/stripeaccounting/&lt;br /&gt;
├── core/modules/modStripeAccounting.class.php   Descripteur (droits, menus, cron, constantes)&lt;br /&gt;
├── class/&lt;br /&gt;
│   ├── StripeApi.class.php                      Wrapper SDK Stripe (lecture seule)&lt;br /&gt;
│   ├── StripeRepository.class.php               Accès SQL + idempotence&lt;br /&gt;
│   ├── StripeLogger.class.php                   Journalisation&lt;br /&gt;
│   ├── StripeAccounting.class.php               Génération des écritures&lt;br /&gt;
│   ├── StripePayout.class.php                   Rapprochement des virements&lt;br /&gt;
│   ├── StripeSync.class.php                     Orchestrateur (point d'entrée du cron)&lt;br /&gt;
│   ├── StripeCsvImporter.class.php              Import CSV&lt;br /&gt;
│   └── actions_stripeaccounting.class.php       Hook 'bankcard'&lt;br /&gt;
├── admin/setup.php                              Configuration&lt;br /&gt;
├── import.php                                   Import CSV&lt;br /&gt;
├── dashboard.php                                Tableau de bord&lt;br /&gt;
├── transaction_list.php                         Liste des transactions&lt;br /&gt;
├── cron/stripe_sync.php                         Point d'entrée CLI&lt;br /&gt;
├── lib/stripeaccounting.lib.php&lt;br /&gt;
├── sql/&lt;br /&gt;
├── langs/{fr_FR,en_US,es_ES,it_IT,de_DE}/&lt;br /&gt;
└── css/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sens des dépendances ===&lt;br /&gt;
&lt;br /&gt;
: pages et hook → &amp;lt;code&amp;gt;StripeSync&amp;lt;/code&amp;gt; → (&amp;lt;code&amp;gt;StripeApi&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StripeRepository&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StripeAccounting&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StripePayout&amp;lt;/code&amp;gt;) → &amp;lt;code&amp;gt;StripeLogger&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:26%;&amp;quot; | Classe !! Rôle&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeApi&amp;lt;/code&amp;gt; || Interroge le SDK Stripe (balance transactions, charges, remboursements, litiges, payouts) avec pagination automatique. Aucun accès base, aucune écriture.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeRepository&amp;lt;/code&amp;gt; || Tout le SQL des deux tables du module. &amp;lt;code&amp;gt;upsertTransaction()&amp;lt;/code&amp;gt; est le point d'idempotence.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeLogger&amp;lt;/code&amp;gt; || Écrit dans &amp;lt;code&amp;gt;llx_stripeaccounting_log&amp;lt;/code&amp;gt; et en miroir dans &amp;lt;code&amp;gt;dol_syslog()&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeAccounting&amp;lt;/code&amp;gt; || Construit les écritures (remboursement, litige, TVA autoliquidation) ou les mouvements bancaires (frais). Expose &amp;lt;code&amp;gt;checkConfig()&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripePayout&amp;lt;/code&amp;gt; || Crée le virement bancaire interne entre le compte Stripe et la banque réelle.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeSync&amp;lt;/code&amp;gt; || Orchestrateur : une méthode par flux, plus &amp;lt;code&amp;gt;reconcileStripeAccount()&amp;lt;/code&amp;gt; qui enchaîne tout.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;StripeCsvImporter&amp;lt;/code&amp;gt; || Alimente le même pipeline depuis un export CSV Stripe.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ActionsStripeAccounting&amp;lt;/code&amp;gt; || Hook &amp;lt;code&amp;gt;bankcard&amp;lt;/code&amp;gt; : lien vers le tableau de bord sur la fiche du compte Stripe.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 4. Synchronisation et idempotence ==&lt;br /&gt;
&lt;br /&gt;
Chaque flux (&amp;lt;code&amp;gt;syncFees&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncRefunds&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncDisputes&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncPayouts&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;syncTransactions&amp;lt;/code&amp;gt;) suit toujours les mêmes étapes :&lt;br /&gt;
&lt;br /&gt;
# '''Vérifier la configuration''' — si elle est incomplète : log &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt;, arrêt immédiat, aucun appel API.&lt;br /&gt;
# '''Lister les objets Stripe''' sur une fenêtre glissante de '''35 jours'''.&lt;br /&gt;
# '''Filtrer''' — un objet est ignoré seulement s'il existe déjà ''et'' que son statut est &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;ignored&amp;lt;/code&amp;gt;. Une ligne en &amp;lt;code&amp;gt;pending&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; est '''retentée''' à ce run.&lt;br /&gt;
# '''Enregistrer''' en statut &amp;lt;code&amp;gt;pending&amp;lt;/code&amp;gt;, puis générer l'écriture ou le mouvement bancaire.&lt;br /&gt;
# '''Conclure''' — succès : statut &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt;. Échec : statut &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; avec le message, et '''le lot continue''' sur l'objet suivant.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #36c; background:#eaf3ff; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Reprise automatique''' — une ligne en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; redevient éligible au run suivant. Une fois la cause corrigée (par exemple un exercice comptable créé tardivement), aucune intervention manuelle n'est nécessaire.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi les doublons sont impossibles ===&lt;br /&gt;
&lt;br /&gt;
* '''Clé unique en base''' sur &amp;lt;code&amp;gt;(stripe_object_id, entity)&amp;lt;/code&amp;gt; — protège même contre deux exécutions concurrentes du cron.&lt;br /&gt;
* '''Test explicite avant traitement''' — évite jusqu'à la tentative d'écriture pour un objet déjà finalisé.&lt;br /&gt;
&lt;br /&gt;
=== Cas particuliers : &amp;lt;code&amp;gt;adjustment&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;payment_failure_refund&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Ce sont des corrections de solde effectuées par Stripe lui-même (réversion après litige, remboursement d'un paiement finalement échoué). Le module les '''enregistre''' — sinon elles resteraient invisibles — mais ne les comptabilise '''jamais''' automatiquement : le signe du montant et la cause varient trop. Elles sont créées directement en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, avec un message explicite, à traiter manuellement.&lt;br /&gt;
&lt;br /&gt;
== 5. Écritures comptables ==&lt;br /&gt;
&lt;br /&gt;
Toutes les lignes d'un même évènement partagent le triplet &amp;lt;code&amp;gt;doc_type='stripeaccounting'&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fk_doc&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;doc_ref&amp;lt;/code&amp;gt; : Dolibarr les regroupe automatiquement sous un même numéro de pièce, sans numérotation propre au module.&lt;br /&gt;
&lt;br /&gt;
=== Vue d'ensemble ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! Évènement !! Ce que fait le module !! Résultat comptable&lt;br /&gt;
|-&lt;br /&gt;
| Frais Stripe ''(TVA &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt;)'' || Mouvement bancaire &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; || Écriture 627xxx / 517xxx générée plus tard par Dolibarr&lt;br /&gt;
|-&lt;br /&gt;
| Frais Stripe ''(mode &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt;)'' || En plus : paire TVA postée immédiatement || Débit TVA déductible, crédit TVA autoliquidation ''(impact net nul)''&lt;br /&gt;
|-&lt;br /&gt;
| Frais Stripe ''(mode &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt;)'' || Écriture directe complète || Débit compte de frais HT + TVA déductible, crédit compte Stripe TTC&lt;br /&gt;
|-&lt;br /&gt;
| Frais d'abonnement / service ''(Radar, Billing, Connect…)'' || Mouvement bancaire &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; || Écriture générée plus tard par Dolibarr, sur le compte fournisseur Stripe&lt;br /&gt;
|-&lt;br /&gt;
| Virement (payout) || Virement bancaire interne entre les 2 comptes || Écriture générée plus tard par Dolibarr&lt;br /&gt;
|-&lt;br /&gt;
| Remboursement ''(facture retrouvée)'' || Écriture directe || Débit compte client 411xxx, crédit compte Stripe 517xxx&lt;br /&gt;
|-&lt;br /&gt;
| Remboursement ''(facture introuvable)'' || Rien || Statut &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, à traiter manuellement&lt;br /&gt;
|-&lt;br /&gt;
| Litige / chargeback || Écriture directe || Débit perte sur litiges 658xxx, crédit compte Stripe 517xxx ''(+ compte de frais si frais associés)''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi frais et virements ne génèrent pas d'écriture directe ===&lt;br /&gt;
&lt;br /&gt;
Le problème historique : quand une facture Stripe est transférée en comptabilité par le workflow standard de Dolibarr, le paiement est comptabilisé pour son montant '''brut''' — les frais sont ignorés à cette étape.&lt;br /&gt;
&lt;br /&gt;
Si le module postait ''en plus'' sa propre écriture ''et'' sa propre ligne bancaire, cette ligne resterait invisible pour &amp;lt;code&amp;gt;bankjournal.php&amp;lt;/code&amp;gt; — qui ne reconnaît que les lignes rattachées à &amp;lt;code&amp;gt;doc_type='bank'&amp;lt;/code&amp;gt;. Un administrateur transférant « normalement » le compte bancaire en comptabilité créait alors une '''seconde''' écriture pour le même mouvement.&lt;br /&gt;
&lt;br /&gt;
'''La solution retenue :''' pour les frais, les frais d'abonnement et les virements, le module ne crée plus que le '''mouvement bancaire réel''', avec les mécanismes natifs de Dolibarr. C'est ensuite le bouton natif ''« Transférer en comptabilité »'' qui produit l'écriture, comme pour n'importe quel autre mouvement bancaire. Le module ne touche donc plus du tout &amp;lt;code&amp;gt;llx_accounting_bookkeeping&amp;lt;/code&amp;gt; dans ces trois cas.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:22%;&amp;quot; | Cas !! Mécanisme natif utilisé&lt;br /&gt;
|-&lt;br /&gt;
| Frais et frais d'abonnement || &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; (mouvement bancaire avec compte de contrepartie, sans tiers ni facture), avec son propre &amp;lt;code&amp;gt;accountancy_code&amp;lt;/code&amp;gt; que &amp;lt;code&amp;gt;bankjournal.php&amp;lt;/code&amp;gt; lit directement.&lt;br /&gt;
|-&lt;br /&gt;
| Virements (payouts) || Virement interne Dolibarr : &amp;lt;code&amp;gt;Account::addline()&amp;lt;/code&amp;gt; des deux côtés, plus &amp;lt;code&amp;gt;add_url_line(…, 'banktransfert')&amp;lt;/code&amp;gt;. La contrepartie est imputée sur &amp;lt;code&amp;gt;ACCOUNTING_ACCOUNT_TRANSFER_CASH&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Dans les deux cas, le statut passe à &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt; — le module a fini son travail — mais '''&amp;lt;code&amp;gt;piece_num&amp;lt;/code&amp;gt; reste vide''' : l'écriture n'existe pas encore, seul &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; est renseigné. Après transfert manuel, on la retrouve avec &amp;lt;code&amp;gt;doc_type='bank'&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;fk_doc&amp;lt;/code&amp;gt; égal au &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; de la ligne.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #fc3; background:#fef6e7; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''À savoir''' — l'écriture des virements ne s'équilibre à zéro sur le compte de transfert que lorsque '''les deux''' comptes bancaires (Stripe ''et'' la banque réelle) ont été transférés en comptabilité, pas seulement un des deux.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #d33; background:#fee7e6; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''⚠ &amp;lt;code&amp;gt;STRIPE_AUTO_RECORD_PAYOUT&amp;lt;/code&amp;gt; doit rester désactivé'''&lt;br /&gt;
&lt;br /&gt;
Dès lors que ce module gère les virements, décochez « Activer l'enregistrement automatique des paiements Stripe » dans &amp;lt;code&amp;gt;stripe/admin/stripe.php&amp;lt;/code&amp;gt; — malgré son libellé, cette case ne concerne que les virements.&lt;br /&gt;
&lt;br /&gt;
Sinon, le webhook du module officiel et ce module créeraient chacun leur propre mouvement bancaire pour le même virement, sans le savoir l'un de l'autre.&lt;br /&gt;
&lt;br /&gt;
Le webhook cœur ne conserve d'ailleurs '''aucune''' trace de l'id du virement traité : en cas de double livraison Stripe (garantie « au moins une fois »), rien ne l'empêche de doublonner tout seul. Ce module, lui, a une vraie idempotence et rattrape automatiquement tout virement manqué sur 35 jours.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Page « Transferts Stripe » masquée ===&lt;br /&gt;
&lt;br /&gt;
À l'activation, &amp;lt;code&amp;gt;modStripeAccounting::init()&amp;lt;/code&amp;gt; désactive l'entrée de menu &amp;lt;code&amp;gt;stripe/payout.php&amp;lt;/code&amp;gt; : cette page interroge l'API en direct sans rien enregistrer, et sa coexistence avec ce module ne créerait qu'une confusion sur ce qui fait foi pour les virements. &amp;lt;code&amp;gt;remove()&amp;lt;/code&amp;gt; restaure la condition d'origine. '''C'est la seule table du cœur que ce module modifie''' — délibéré, et documenté ici pour cette raison.&lt;br /&gt;
&lt;br /&gt;
=== Frais par transaction ou frais d'abonnement ? ===&lt;br /&gt;
&lt;br /&gt;
Stripe facture deux choses distinctes sous le mot « frais » :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! !! Frais par transaction !! Frais d'abonnement / service&lt;br /&gt;
|-&lt;br /&gt;
! Exemple&lt;br /&gt;
| Commission sur chaque encaissement || Radar, Billing, Connect&lt;br /&gt;
|-&lt;br /&gt;
! Où le trouver&lt;br /&gt;
| Champ &amp;lt;code&amp;gt;.fee&amp;lt;/code&amp;gt; d'une balance transaction de type &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; || Balance transaction dédiée, de type &amp;lt;code&amp;gt;stripe_fee&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;application_fee&amp;lt;/code&amp;gt; ''(le &amp;lt;code&amp;gt;.fee&amp;lt;/code&amp;gt; y vaut toujours 0, le montant est dans &amp;lt;code&amp;gt;.amount&amp;lt;/code&amp;gt;)''&lt;br /&gt;
|-&lt;br /&gt;
! Compte utilisé&lt;br /&gt;
| Compte de frais configuré (627xxx) || Code comptable fournisseur du tiers Stripe configuré&lt;br /&gt;
|-&lt;br /&gt;
! Type en base&lt;br /&gt;
| &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Limite du mode TVA &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Ce mode doit scinder le montant TTC en HT + TVA, un découpage que &amp;lt;code&amp;gt;PaymentVarious&amp;lt;/code&amp;gt; ne sait pas exprimer. Il reste donc sur l'ancien comportement : écriture directe complète, aucun mouvement bancaire créé. Pas de risque de doublon (puisque aucune ligne bancaire n'est produite), mais le solde &amp;lt;code&amp;gt;llx_bank&amp;lt;/code&amp;gt; du compte Stripe ne reflétera jamais les frais tant que ce mode est actif.&lt;br /&gt;
&lt;br /&gt;
== 6. Import CSV ==&lt;br /&gt;
&lt;br /&gt;
L'import couvre le cas d'un compte Stripe '''différent''' de celui configuré dans le module officiel — par exemple une autre boutique PrestaShop avec son propre compte marchand. L'API n'y a pas accès : le contenu est exporté en CSV depuis le dashboard Stripe, puis importé.&lt;br /&gt;
&lt;br /&gt;
=== Hypothèse de départ ===&lt;br /&gt;
&lt;br /&gt;
Les factures et paiements de cette boutique sont '''déjà''' comptabilisés dans Dolibarr par un autre processus, et l'encaissement (débit 517, crédit 411) est déjà posé. Seuls manquent les '''frais''', les '''remboursements''' et les '''virements''' — c'est exactement ce que l'import traite.&lt;br /&gt;
&lt;br /&gt;
=== Interface : un seul champ ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;import.php&amp;lt;/code&amp;gt; n'expose plus qu'un champ d'upload, '''Historique général''', câblé sur &amp;lt;code&amp;gt;importGeneralHistory()&amp;lt;/code&amp;gt;. Ce fichier couvre à lui seul tous les types de mouvements.&lt;br /&gt;
&lt;br /&gt;
Les méthodes &amp;lt;code&amp;gt;importPayments()&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;importPayouts()&amp;lt;/code&amp;gt; restent implémentées et fonctionnelles, mais ne sont plus atteignables depuis l'interface ; elles sont documentées ci-dessous pour mémoire.&lt;br /&gt;
&lt;br /&gt;
Comme le bouton « Synchroniser maintenant », l'import est bloqué — bandeau d'alerte, bouton désactivé, garde-fou côté serveur — tant que la configuration est incomplète.&lt;br /&gt;
&lt;br /&gt;
=== Les trois méthodes ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:24%;&amp;quot; | Méthode !! Export Stripe lu !! Traitement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;importGeneralHistory()&amp;lt;/code&amp;gt;&amp;lt;br /&amp;gt;''(seule exposée)'' || Balance history || Aiguillage par colonne &amp;lt;code&amp;gt;Type&amp;lt;/code&amp;gt;, voir tableau ci-dessous&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;importPayments()&amp;lt;/code&amp;gt; || Payments || Frais → écriture de frais. Montant remboursé → ligne &amp;lt;code&amp;gt;refund&amp;lt;/code&amp;gt; toujours en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;importPayouts()&amp;lt;/code&amp;gt; || Payouts || Exactement le même traitement qu'un payout venu de l'API&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Aiguillage de l'historique général, par colonne &amp;lt;code&amp;gt;Type&amp;lt;/code&amp;gt; :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:30%;&amp;quot; | Type Stripe !! Traitement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt; || Virement bancaire interne, comme via l'API&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;payment&amp;lt;/code&amp;gt; avec frais || Mouvement de frais&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_fee&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;application_fee&amp;lt;/code&amp;gt; || Frais d'abonnement, sur le compte fournisseur Stripe&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;refund&amp;lt;/code&amp;gt; || Enregistré, '''toujours''' en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;payout_minimum_balance_hold&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;…_release&amp;lt;/code&amp;gt; || '''Ignorés''' — réserve glissante Stripe, impact net nul, rien à comptabiliser&lt;br /&gt;
|-&lt;br /&gt;
| tout autre type || Enregistré en &amp;lt;code&amp;gt;type='other'&amp;lt;/code&amp;gt;, statut &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, type brut conservé dans la description. Aucune écriture devinée.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les colonnes sont reconnues '''par leur nom''' : l'ordre importe peu, et les colonnes en plus non utilisées sont ignorées.&lt;br /&gt;
&lt;br /&gt;
=== Idempotence de l'import ===&lt;br /&gt;
&lt;br /&gt;
La clé unique protège contre tout double import : réimporter le même CSV, ou un CSV qui chevauche un import précédent, ne crée aucun doublon.&lt;br /&gt;
&lt;br /&gt;
Point important : dans l'historique général, les lignes &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;payment&amp;lt;/code&amp;gt; sont indexées par leur colonne '''&amp;lt;code&amp;gt;Source&amp;lt;/code&amp;gt;''' (&amp;lt;code&amp;gt;po_…&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ch_…&amp;lt;/code&amp;gt;), pas par l'&amp;lt;code&amp;gt;id&amp;lt;/code&amp;gt; de la ligne (&amp;lt;code&amp;gt;txn_…&amp;lt;/code&amp;gt;) — soit exactement la même clé que les imports dédiés. Importer l'historique général '''en plus''' des exports spécifiques ne poste donc jamais deux fois la même écriture, quel que soit l'ordre.&lt;br /&gt;
&lt;br /&gt;
Les identifiants Stripe étant uniques à l'échelle de la plateforme, mélanger dans la même table des lignes venant du compte API et de plusieurs comptes importés en CSV ne présente aucun risque de collision.&lt;br /&gt;
&lt;br /&gt;
=== Détails pratiques ===&lt;br /&gt;
&lt;br /&gt;
* '''Libellé source''' — un champ libre saisi à l'import (ex. « Boutique DRM ») est stocké sur chaque ligne créée et sert de colonne et de filtre dans la liste, pour distinguer plusieurs boutiques côte à côte.&lt;br /&gt;
* '''Format des montants''' — les CSV Stripe utilisent la virgule décimale française, convertie via &amp;lt;code&amp;gt;price2num()&amp;lt;/code&amp;gt;. Les dates marquées &amp;lt;code&amp;gt;(UTC)&amp;lt;/code&amp;gt; sont interprétées comme telles.&lt;br /&gt;
&lt;br /&gt;
== 7. Configuration ==&lt;br /&gt;
&lt;br /&gt;
La clé API et le mode test/live ne sont '''pas''' ressaisis ici : ils sont lus en lecture seule depuis le module Stripe officiel.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:26%;&amp;quot; | Champ !! Constante !! Usage&lt;br /&gt;
|-&lt;br /&gt;
| Compte financier Stripe || &amp;lt;code&amp;gt;STRIPE_BANK_ACCOUNT_FOR_PAYMENTS&amp;lt;/code&amp;gt; ''(constante du module officiel)'' || Sélecteur de compte bancaire. Aucune copie locale, donc aucun risque de divergence.&lt;br /&gt;
|-&lt;br /&gt;
| Compte bancaire principal || &amp;lt;code&amp;gt;STRIPE_BANK_ACCOUNT_FOR_BANKTRANSFERS&amp;lt;/code&amp;gt; ''(constante du module officiel)'' || Même sélecteur. Voir l'encadré ci-dessous.&lt;br /&gt;
|-&lt;br /&gt;
| Compte de frais || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_FRAIS&amp;lt;/code&amp;gt; || Numéro de compte, ex. 627xxx&lt;br /&gt;
|-&lt;br /&gt;
| Compte de litiges || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_LITIGES&amp;lt;/code&amp;gt; || Numéro de compte, ex. 658xxx. '''Requis''' — utilisé dès qu'un litige survient, quel que soit le mode TVA.&lt;br /&gt;
|-&lt;br /&gt;
| Tiers fournisseur Stripe || &amp;lt;code&amp;gt;STRIPEACCOUNTING_FOURNISSEUR_STRIPE_ID&amp;lt;/code&amp;gt; || Tiers marqué fournisseur ; c'est son code comptable fournisseur qui est utilisé. Optionnel, sauf s'il existe des frais d'abonnement.&lt;br /&gt;
|-&lt;br /&gt;
| Mode TVA || &amp;lt;code&amp;gt;STRIPEACCOUNTING_VAT_MODE&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Compte TVA déductible (intracommunautaire) || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_TVA_DEDUCTIBLE&amp;lt;/code&amp;gt; || Requis si mode TVA ≠ &amp;lt;code&amp;gt;none&amp;lt;/code&amp;gt;. Stripe facturant toujours depuis une entité UE non française, la TVA déductible est intracommunautaire dans tous les cas.&lt;br /&gt;
|-&lt;br /&gt;
| Compte de TVA due (intracommunautaire) || &amp;lt;code&amp;gt;STRIPEACCOUNTING_COMPTE_TVA_AUTOLIQUIDATION&amp;lt;/code&amp;gt; || Requis en mode &amp;lt;code&amp;gt;autoliquidation&amp;lt;/code&amp;gt; uniquement — jamais utilisé en mode &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| Taux de TVA || &amp;lt;code&amp;gt;STRIPEACCOUNTING_VAT_RATE&amp;lt;/code&amp;gt; || Pourcentage, 20 par défaut&lt;br /&gt;
|-&lt;br /&gt;
| Fréquence de synchronisation || &amp;lt;code&amp;gt;STRIPEACCOUNTING_SYNC_UNITFREQUENCY&amp;lt;/code&amp;gt; || Répercutée sur la tâche planifiée (en secondes)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #36c; background:#eaf3ff; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Pourquoi redéfinir le compte bancaire principal ici ?'''&lt;br /&gt;
&lt;br /&gt;
La page de configuration du module Stripe officiel n'affiche ce champ que si &amp;lt;code&amp;gt;STRIPE_AUTO_RECORD_PAYOUT&amp;lt;/code&amp;gt; est activé — et son handler de sauvegarde remet la valeur à 0 à chaque enregistrement tant que le champ n'est pas rendu. Or ce réglage doit justement rester désactivé quand ce module gère les virements. Le champ est donc réexposé ici, en écrivant directement la constante du cœur, pour que la valeur reste configurable et stable.&lt;br /&gt;
&lt;br /&gt;
Les deux sélecteurs de compte n'écrivent leur constante que si un compte réel a été soumis : enregistrer la page pour un tout autre champ n'écrase jamais une valeur correcte.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Vérification de la configuration ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;StripeAccounting::checkConfig()&amp;lt;/code&amp;gt; renvoie la liste des constantes manquantes. Elle est appelée à la fois par la page de configuration (bandeau d'information) et par chaque point d'entrée de synchronisation (garde-fou réel qui bloque tout traitement).&lt;br /&gt;
&lt;br /&gt;
=== Piège des sélecteurs de compte comptable ===&lt;br /&gt;
&lt;br /&gt;
Les quatre champs utilisant &amp;lt;code&amp;gt;FormAccounting::select_account()&amp;lt;/code&amp;gt; (frais, litiges, les deux comptes TVA) ont une option « rien sélectionné » dont la valeur est '''&amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;''' — une chaîne non vide, donc vraie en PHP. Un champ laissé vide et enregistré stocke littéralement &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;StripeAccounting::getAccountConst()&amp;lt;/code&amp;gt; normalise cette valeur en chaîne vide à la lecture, partout où ces constantes sont lues. Aucune écriture ne peut donc atterrir sur le compte inexistant &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 8. Interface ==&lt;br /&gt;
&lt;br /&gt;
=== Tableau de bord ===&lt;br /&gt;
&lt;br /&gt;
Solde Stripe (appel API en direct), nombre de transactions non rapprochées, total des frais du mois, payouts en attente, et bouton '''Synchroniser maintenant''' — désactivé, avec bandeau listant les constantes manquantes, tant que la configuration est incomplète.&lt;br /&gt;
&lt;br /&gt;
=== Liste des transactions ===&lt;br /&gt;
&lt;br /&gt;
Liste paginée, triable et filtrable, construite avec le même mécanisme que les listes natives Dolibarr : l'icône en haut à droite du tableau permet à chaque utilisateur de choisir ses colonnes, et la préférence est mémorisée par utilisateur.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:20%;&amp;quot; | Colonne !! Contenu&lt;br /&gt;
|-&lt;br /&gt;
| Montant, Frais, Total || Le popup sur les frais indique la TVA sur frais quand une paire d'autoliquidation ou une TVA française a été postée&lt;br /&gt;
|-&lt;br /&gt;
| Type, Description || Popup avec l'ID Stripe, l'ID d'évènement ou de source, et la description complète non tronquée&lt;br /&gt;
|-&lt;br /&gt;
| Tiers || Le client résolu via la facture, ou via la charge source pour son frais associé, ou le tiers fournisseur Stripe pour un frais d'abonnement&lt;br /&gt;
|-&lt;br /&gt;
| Écriture || Lien « Pièce n°X » vers l'écriture, et/ou lien vers le mouvement bancaire associé — voir la nuance ci-dessous&lt;br /&gt;
|-&lt;br /&gt;
| Source, Statut || Le badge &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; ouvre un popup avec le message d'erreur complet : plus besoin d'aller en base pour comprendre un échec&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #fc3; background:#fef6e7; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''Lire la colonne « Écriture »''' — sur une ligne &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt; ou &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt;, le lien pointe vers le '''mouvement bancaire''', pas vers une pièce comptable. Le &amp;lt;code&amp;gt;piece_num&amp;lt;/code&amp;gt; du module, lui, n'est jamais l'écriture 627/517 du frais : c'est uniquement la paire TVA d'autoliquidation. L'écriture du frais est générée plus tard, par le bouton natif de Dolibarr, et n'est jamais reportée sur cette ligne.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La page est '''purement consultative''' : aucune comptabilisation manuelle n'y est proposée. Le module comptabilise automatiquement, et le transfert en comptabilité des frais et virements se fait depuis le bouton natif « Transférer en comptabilité ».&lt;br /&gt;
&lt;br /&gt;
=== Lignes &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Chaque paiement produit '''deux lignes''' en base :&lt;br /&gt;
&lt;br /&gt;
* une ligne &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt;, toujours en statut &amp;lt;code&amp;gt;ignored&amp;lt;/code&amp;gt;, frais à 0, jamais traitée — présente uniquement pour l'idempotence ;&lt;br /&gt;
* une ligne &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; pour le même paiement, liée à la première.&lt;br /&gt;
&lt;br /&gt;
Les deux apparaissent séparément dans la liste, mais la ligne &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt; porte elle aussi le lien vers le paiement et la facture, résolu par jointure.&lt;br /&gt;
&lt;br /&gt;
=== Bandeau mode test ===&lt;br /&gt;
&lt;br /&gt;
Tant que le mode live n'est pas activé, le tableau de bord, la page de configuration et la liste des transactions affichent tous les trois le même avertissement que le module Stripe officiel. Impossible d'oublier qu'on travaille en mode test.&lt;br /&gt;
&lt;br /&gt;
=== Menus ===&lt;br /&gt;
&lt;br /&gt;
Tout est regroupé sous '''Banques et caisses → Compte Stripe''' (menu du module officiel), à plat, en trois entrées de même niveau :&lt;br /&gt;
&lt;br /&gt;
# Tableau de bord Stripe&lt;br /&gt;
# Transactions Stripe&lt;br /&gt;
# Import CSV ''(réservé aux administrateurs)''&lt;br /&gt;
&lt;br /&gt;
Un lien vers le tableau de bord est aussi ajouté automatiquement sur la fiche du compte bancaire configuré comme compte Stripe.&lt;br /&gt;
&lt;br /&gt;
== 9. Tâche planifiée ==&lt;br /&gt;
&lt;br /&gt;
Deux façons d'exécuter la synchronisation, toutes deux idempotentes et sans risque à relancer. Dans les deux cas le code exécuté est strictement le même : aucune divergence de comportement.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:4px solid #d33; background:#fee7e6; padding:0.6em 1em; margin:1em 0;&amp;quot;&amp;gt;&lt;br /&gt;
'''⚠ Aucune des deux ne démarre toute seule.'''&lt;br /&gt;
&lt;br /&gt;
L'activation du module crée la tâche &amp;lt;code&amp;gt;StripeAccountingSync&amp;lt;/code&amp;gt;, mais '''désactivée par défaut'''. Et même activée, l'ordonnanceur Dolibarr n'est déclenché par rien tant qu'aucune crontab système ne l'appelle. Sans ces deux étapes, la synchro n'a lieu qu'au clic manuel sur « Synchroniser maintenant ».&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Étape 1 — activer la tâche ===&lt;br /&gt;
&lt;br /&gt;
Dans '''Accueil → Configuration → Modules → Tâches planifiées'''. &amp;lt;code&amp;gt;llx_cronjob&amp;lt;/code&amp;gt; étant une table du cœur, ce réglage se fait uniquement par l'interface, jamais en SQL direct depuis le module.&lt;br /&gt;
&lt;br /&gt;
=== Étape 2 — un déclencheur système ===&lt;br /&gt;
&lt;br /&gt;
Au choix, l'une des deux options.&lt;br /&gt;
&lt;br /&gt;
'''Option A — ordonnanceur Dolibarr''' ''(recommandé si plusieurs tâches planifiées coexistent)''. Lance toutes les tâches dues, pas seulement celle-ci. Nécessite l'étape 1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
*/15 * * * * curl &amp;quot;https://votre-dolibarr/public/cron/cron_run_jobs_by_url.php?securitykey=VOTRE_CLE&amp;amp;userlogin=VOTRE_LOGIN&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La clé de sécurité se génère sur la page des tâches planifiées, bouton « Sécurité de l'exécution des tâches par URL ».&lt;br /&gt;
&lt;br /&gt;
'''Option B — script CLI du module.''' Autonome, refuse l'exécution depuis un navigateur, et indépendant de l'état activé ou non de la tâche Dolibarr.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
*/15 * * * * php /chemin/vers/htdocs/custom/stripeaccounting/cron/stripe_sync.php &amp;gt;&amp;gt; /var/log/stripeaccounting.log 2&amp;gt;&amp;amp;1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 10. Journalisation et permissions ==&lt;br /&gt;
&lt;br /&gt;
=== Journalisation ===&lt;br /&gt;
&lt;br /&gt;
Chaque appel API, écriture générée, avertissement ou erreur est tracé dans &amp;lt;code&amp;gt;llx_stripeaccounting_log&amp;lt;/code&amp;gt;, consultable en base ou via le fichier de log standard Dolibarr. Niveaux : &amp;lt;code&amp;gt;DEBUG&amp;lt;/code&amp;gt; &amp;lt; &amp;lt;code&amp;gt;INFO&amp;lt;/code&amp;gt; &amp;lt; &amp;lt;code&amp;gt;WARNING&amp;lt;/code&amp;gt; &amp;lt; &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt;. La colonne &amp;lt;code&amp;gt;context&amp;lt;/code&amp;gt; contient le détail structuré en JSON (payload API, montants calculés…).&lt;br /&gt;
&lt;br /&gt;
=== Permissions ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Droit !! Contrôle&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;read&amp;lt;/code&amp;gt; || Consultation du tableau de bord et de la liste&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;write&amp;lt;/code&amp;gt; || Déclarée pour la configuration, mais non vérifiée dans le code aujourd'hui&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;reconcile&amp;lt;/code&amp;gt; || Déclenchement manuel de la synchronisation&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
En pratique, &amp;lt;code&amp;gt;admin/setup.php&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;import.php&amp;lt;/code&amp;gt; ne contrôlent que le statut '''administrateur Dolibarr''', pas le droit &amp;lt;code&amp;gt;write&amp;lt;/code&amp;gt; : seuls les administrateurs peuvent configurer le module ou importer un CSV, quoi qu'il soit coché dans les permissions.&lt;br /&gt;
&lt;br /&gt;
== 11. Base de données ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;llx_stripeaccounting_transaction&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Une ligne par objet Stripe traité — charge, frais, remboursement, litige ou virement — tous dans la même table, distingués par la colonne &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:24%;&amp;quot; | Colonne !! style=&amp;quot;width:16%;&amp;quot; | Type !! Rôle&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;rowid&amp;lt;/code&amp;gt; || int AI || Clé primaire&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;entity&amp;lt;/code&amp;gt; || int || Multi-société Dolibarr&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_object_id&amp;lt;/code&amp;gt; || varchar(80) || Identifiant Stripe — '''ancre d'idempotence'''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_event_id&amp;lt;/code&amp;gt; || varchar(80) || Identifiant d'évènement, informatif seulement&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt; || varchar(20) || &amp;lt;code&amp;gt;charge&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;refund&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;dispute&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;payout&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;other&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;stripe_source_id&amp;lt;/code&amp;gt; || varchar(80) || Objet Stripe source (ex. la charge liée à un remboursement)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;source_label&amp;lt;/code&amp;gt; || varchar(80) || Libellé libre saisi à l'import CSV ; vide pour les lignes venues de l'API&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;description&amp;lt;/code&amp;gt; || varchar(255) || Libellé Stripe&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;amount&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;net&amp;lt;/code&amp;gt; || decimal(24,8) || Montants déjà convertis depuis les centimes Stripe&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;currency&amp;lt;/code&amp;gt; || varchar(3) || Code devise ISO&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;date_created&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;date_available_on&amp;lt;/code&amp;gt; || datetime || Dates côté Stripe&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_facture&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fk_paiement&amp;lt;/code&amp;gt; || int || Facture et paiement Dolibarr résolus, si trouvés&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; || int || Ligne &amp;lt;code&amp;gt;llx_bank&amp;lt;/code&amp;gt; générée ''(vide pour un frais en mode TVA &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt;)''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;piece_num&amp;lt;/code&amp;gt; || varchar(20) || Numéro de pièce comptable généré, quand il y en a un&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt; || varchar(16) || &amp;lt;code&amp;gt;pending&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;reconciled&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ignored&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;error_message&amp;lt;/code&amp;gt; || text || Détail en cas d'erreur&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;date_creation&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;date_processed&amp;lt;/code&amp;gt; || datetime || Horodatage technique&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_user_creat&amp;lt;/code&amp;gt; || int || Utilisateur ayant déclenché le traitement&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Clé unique''' sur &amp;lt;code&amp;gt;(stripe_object_id, entity)&amp;lt;/code&amp;gt; — c'est elle qui garantit qu'un même objet Stripe ne peut jamais être inséré deux fois, même en cas d'exécutions concurrentes.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;llx_stripeaccounting_log&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Colonne !! Rôle&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;level&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;DEBUG&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;INFO&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;WARNING&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ERROR&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;message&amp;lt;/code&amp;gt; || Message court&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;context&amp;lt;/code&amp;gt; || Contexte structuré en JSON&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;fk_stripeaccounting_transaction&amp;lt;/code&amp;gt; || Transaction liée, si applicable&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;datec&amp;lt;/code&amp;gt; || Horodatage&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 12. Dépannage ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:26%;&amp;quot; | Symptôme !! Cause probable !! Action&lt;br /&gt;
|-&lt;br /&gt;
| Le bouton « Synchroniser maintenant » est désactivé || Configuration minimale incomplète || Compléter les champs listés dans le bandeau d'alerte de la page de configuration&lt;br /&gt;
|-&lt;br /&gt;
| Une transaction reste en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; || Écriture refusée par Dolibarr (compte inexistant, période clôturée), ou remboursement non rattaché || Lire &amp;lt;code&amp;gt;error_message&amp;lt;/code&amp;gt; sur la ligne, puis le détail dans la table de logs&lt;br /&gt;
|-&lt;br /&gt;
| Le solde Stripe ne s'affiche pas || Clé API manquante ou invalide dans le module Stripe officiel || Vérifier &amp;lt;code&amp;gt;stripe/admin/stripe.php&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Un remboursement n'est jamais rapproché || Le paiement d'origine n'a pas été retrouvé via &amp;lt;code&amp;gt;ext_payment_id&amp;lt;/code&amp;gt; || Vérifier que le paiement Stripe a bien été enregistré par le module officiel avec cet identifiant&lt;br /&gt;
|-&lt;br /&gt;
| Un &amp;lt;code&amp;gt;subscription_fee&amp;lt;/code&amp;gt; reste en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; || Tiers fournisseur Stripe non renseigné, ou sans code comptable fournisseur || Renseigner le champ en configuration, et compléter la fiche du tiers&lt;br /&gt;
|-&lt;br /&gt;
| Un remboursement importé en CSV reste en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt; || '''Normal et attendu''' — ce compte n'est pas relié à &amp;lt;code&amp;gt;ext_payment_id&amp;lt;/code&amp;gt; || Traiter la facture et le remboursement manuellement en comptabilité&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 13. Pièges rencontrés ==&lt;br /&gt;
&lt;br /&gt;
Notes de développement, conservées pour éviter de retomber dedans.&lt;br /&gt;
&lt;br /&gt;
* '''&amp;lt;code&amp;gt;PaymentVarious::create()&amp;lt;/code&amp;gt;''' ne met à jour &amp;lt;code&amp;gt;fk_bank&amp;lt;/code&amp;gt; qu'en base, jamais sur l'objet PHP. Un &amp;lt;code&amp;gt;fetch()&amp;lt;/code&amp;gt; après &amp;lt;code&amp;gt;create()&amp;lt;/code&amp;gt; est indispensable pour récupérer la vraie valeur.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;select_comptes()&amp;lt;/code&amp;gt;''' affiche son propre HTML ''et'' retourne le nombre de comptes. L'appeler en instruction nue : l'envelopper dans &amp;lt;code&amp;gt;print&amp;lt;/code&amp;gt; réafficherait ce nombre juste après la balise select.&lt;br /&gt;
* '''&amp;lt;code&amp;gt;master.inc.php&amp;lt;/code&amp;gt;, pas &amp;lt;code&amp;gt;main.inc.php&amp;lt;/code&amp;gt;''' pour le script CLI. Le second attend une session HTTP et, en pur CLI, se termine silencieusement — aucune sortie, aucun log, code retour 0 — dans sa redirection vers la page de connexion. L'impression trompeuse que le script « ne fait rien » plutôt qu'une vraie erreur.&lt;br /&gt;
* '''Bibliothèques du cœur''' — &amp;lt;code&amp;gt;master.inc.php&amp;lt;/code&amp;gt; ne charge pas tout ce que &amp;lt;code&amp;gt;main.inc.php&amp;lt;/code&amp;gt; charge pour le web (par exemple &amp;lt;code&amp;gt;core/lib/date.lib.php&amp;lt;/code&amp;gt;, requis par &amp;lt;code&amp;gt;BookKeeping&amp;lt;/code&amp;gt;). À inclure explicitement si le script CLI évolue.&lt;br /&gt;
* '''Option « rien sélectionné » à &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;''' dans les sélecteurs de compte comptable — voir la section Configuration.&lt;br /&gt;
&lt;br /&gt;
== 14. Limites connues ==&lt;br /&gt;
&lt;br /&gt;
* '''Devises « zéro décimale »''' (JPY, KRW…) non gérées : les montants sont divisés par 100 en supposant deux décimales. Usage prévu : EUR.&lt;br /&gt;
* '''Fenêtre de 35 jours''' non configurable. Une synchronisation interrompue plus longtemps devra être rattrapée manuellement.&lt;br /&gt;
* '''Rattachement des remboursements''' — dépend de &amp;lt;code&amp;gt;ext_payment_id&amp;lt;/code&amp;gt; et &amp;lt;code&amp;gt;ext_payment_site&amp;lt;/code&amp;gt; sur &amp;lt;code&amp;gt;llx_paiement&amp;lt;/code&amp;gt;, renseignés par le flux de paiement Stripe standard. Un paiement enregistré autrement ne pourra pas être rattaché automatiquement. Le rattachement se fait via le '''PaymentIntent id''', jamais via l'id de charge : le module Stripe du cœur ne stocke jamais ce dernier ''(il y met soit le PaymentIntent brut, soit un composite, selon le chemin de paiement emprunté)''.&lt;br /&gt;
* '''Import CSV en notation française''' uniquement : un export à point décimal ne serait pas interprété correctement.&lt;br /&gt;
* '''Colonne « Transfer » du CSV Paiements''' stockée à titre informatif seulement : elle ne sert pas à vérifier que le total des paiements correspond au montant du virement importé.&lt;br /&gt;
* '''Remboursements importés en CSV toujours en &amp;lt;code&amp;gt;error&amp;lt;/code&amp;gt;''' — comportement voulu, pas un bug.&lt;br /&gt;
* '''Mode TVA &amp;lt;code&amp;gt;french&amp;lt;/code&amp;gt;''' — le solde bancaire du compte Stripe ne reflète pas les frais, voir section 5.&lt;br /&gt;
&lt;br /&gt;
[[Catégorie:Dolibarr]]&lt;br /&gt;
[[Catégorie:Modules]]&lt;br /&gt;
[[Catégorie:Comptabilité]]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Liste_de_nos_modules&amp;diff=535</id>
		<title>Liste de nos modules</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Liste_de_nos_modules&amp;diff=535"/>
				<updated>2026-08-02T04:54:11Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : /* Modules Dolibarr */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Modules Dolibarr ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;0&amp;quot; style=&amp;quot;border-collapse:collapse&amp;quot;&lt;br /&gt;
| [[Fichier:addremise_box.png|160px|thumb|left|link=Addremise|Ajoutez des remises facilement]]&lt;br /&gt;
| [[Fichier:viewmap_box.png|160px|thumb|left|link=Viewmap|Afffichez une carte de tous vos contacts]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Fichier:exportpresta_box.png|160px|thumb|left|link=Exportpresta|Exportez vos produits sur PrestShop]]&lt;br /&gt;
| [[Fichier:jaquette_addinventory.png|160px|thumb|left|link=Addinventory|Corrigez votre stock facilement]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Fichier:modEANPRODOC.png|160px|thumb|left|link=Eanprodoc|Afficher les codes-barres de vos produits dans vos documents PDF]]&lt;br /&gt;
| [[Fichier:modEANPRODOC.png|160px|thumb|left|link=Stripeaccounting|Ventilation des frais Stripe avec Dolibarr]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Modules Prestashop 1.6 &amp;amp; 1.8 ==&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;0&amp;quot; style=&amp;quot;border-collapse:collapse&amp;quot;&lt;br /&gt;
| [[Fichier:dolistock_box.png|256px|thumb|left|link=Dolistock|Synchronisez votre stock entre Dolibarr et PrestaShop]]&lt;br /&gt;
| [[Fichier:256px-bestdefaultcombination_box.png|256px|thumb|left|link=best default combination|Module Remplacer automatiquement vos déclinaisons par défaut avec stratégie]]&lt;br /&gt;
| [[Fichier:256px-bypassinvoice_box.png|256px|thumb|left|link=Bypassinvoice|Déléguer la gestion des vos factures Prestashop à Dolibarr]]&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Contact ==&lt;br /&gt;
&lt;br /&gt;
Pour toutes questions sur les produits et services, veuillez nous contacter:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Siladel.png|link=https://www.siladel.fr|Développement e-commerce sur mesure]]&lt;br /&gt;
&lt;br /&gt;
[https://www.dolistore.com/index.php?controller=search&amp;amp;search_query=siladel&amp;amp;submit_search= Catalogue de nos modules disponibles à l’achat pour Dolibarr]&lt;br /&gt;
&lt;br /&gt;
[https://www.siladel.fr/service/infogerance TMA de vos applications Web]&lt;br /&gt;
&lt;br /&gt;
[https://www.siladel.fr/service/developpement-sur-mesure Développement web sur mesure]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Addinventory&amp;diff=534</id>
		<title>Addinventory</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Addinventory&amp;diff=534"/>
				<updated>2025-08-30T10:39:32Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''ADDINVENTORY''' est un module Dolibarr qui permet de '''modifier et corriger rapidement vos stocks''' à partir d’une liste de produits, de lots ou de déclinaisons.  &lt;br /&gt;
&lt;br /&gt;
Principales fonctionnalités :  &lt;br /&gt;
* Correction en masse du stock à partir d’une liste (lots et déclinaisons inclus).  &lt;br /&gt;
* Création en masse de lots.  &lt;br /&gt;
* Gain de temps significatif lors des mouvements de stocks.  &lt;br /&gt;
* Tableau de suivi permettant un aperçu global des références en un coup d’œil.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Compatible avec Dolibarr 6 et versions supérieures.  &lt;br /&gt;
&lt;br /&gt;
# Depuis l’interface Dolibarr, allez dans '''Configuration &amp;gt; Modules/Applications'''.  &lt;br /&gt;
# Cliquez sur l’onglet '''Déployer/Installer un module externe'''.  &lt;br /&gt;
&lt;br /&gt;
Une fois l’installation terminée, les pages '''Inventaire &amp;amp; correction''' et '''Stocks référents''' seront disponibles dans l’onglet '''Produits | Services'''.  &lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Conf addinventory2.png|880px]]  &lt;br /&gt;
&lt;br /&gt;
=== Activer les quantités décimales ===&lt;br /&gt;
Permet la gestion des stocks avec des valeurs décimales.  &lt;br /&gt;
&lt;br /&gt;
=== Correction par quantité Delta ===&lt;br /&gt;
Indiquez la quantité à ajouter ou à supprimer.  &lt;br /&gt;
Vous pouvez saisir directement une valeur (positive ou négative) ou utiliser les flèches pour ajuster la quantité.  &lt;br /&gt;
&lt;br /&gt;
=== Correction par substitution ===&lt;br /&gt;
Renseignez directement la quantité totale de produit disponible en stock.  &lt;br /&gt;
&lt;br /&gt;
=== Choix du mode (Delta ou Substitution) ===&lt;br /&gt;
Autorise les utilisateurs à basculer entre les deux méthodes dans la page '''Inventaire &amp;amp; correction'''.  &lt;br /&gt;
&lt;br /&gt;
=== Modification du stock des produits parents avec variantes ===&lt;br /&gt;
Par défaut, Dolibarr interdit la saisie de stock sur les produits parents à variantes.  &lt;br /&gt;
Cette option permet de forcer la correction dans certains cas spécifiques (ex. rattrapage d’erreurs).  &lt;br /&gt;
&lt;br /&gt;
=== Afficher les services ===&lt;br /&gt;
Inclut également les produits de type service dans les listes.  &lt;br /&gt;
&lt;br /&gt;
=== Activer la saisie du prix d’achat ===&lt;br /&gt;
Ajoute la possibilité de saisir le prix d’achat unitaire pour tous les produits nouvellement ajoutés.  &lt;br /&gt;
&lt;br /&gt;
=== Création de nouveaux lots ===&lt;br /&gt;
Pour les produits gérés en lots, cette option affiche directement les champs nécessaires :  &lt;br /&gt;
*n° de lot  &lt;br /&gt;
*entrepôt  &lt;br /&gt;
*DLC  &lt;br /&gt;
*DMD/DLUO  &lt;br /&gt;
*prix d’achat  &lt;br /&gt;
*stock  &lt;br /&gt;
&lt;br /&gt;
[[Fichier:Conf addinventory list.png|900px]]  &lt;br /&gt;
&lt;br /&gt;
== Fonctionnement de la correction du stock ==&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Doc_addinventory.png|880px]]  &lt;br /&gt;
&lt;br /&gt;
Pour modifier le stock d’un produit, indiquez soit la quantité totale disponible, soit un delta (en fonction du mode défini).  &lt;br /&gt;
&lt;br /&gt;
=== Mode quantité Delta ===&lt;br /&gt;
Saisissez une variation de stock (exemple : +10 ou -5).  &lt;br /&gt;
Cela ne remplace pas la valeur finale, mais ajuste le stock existant.  &lt;br /&gt;
&lt;br /&gt;
=== Mode Substitution ===&lt;br /&gt;
Saisissez directement la quantité totale disponible en stock.  &lt;br /&gt;
&lt;br /&gt;
Pour valider les modifications, cliquez sur le bouton '''Enregistrer''' en bas de page.  &lt;br /&gt;
&lt;br /&gt;
'''Important :''' lors d’une recherche filtrée par entrepôt, seuls les produits ayant un stock existant apparaissent. Pour afficher tous les produits, effectuez la recherche sans préciser d’entrepôt.  &lt;br /&gt;
&lt;br /&gt;
[[Fichier:Addinventory_screen04.jpg|880px]]  &lt;br /&gt;
&lt;br /&gt;
Chaque correction enregistre automatiquement un mouvement de stock dans Dolibarr, avec le delta de quantité (positif ou négatif), quelle que soit la méthode choisie.  &lt;br /&gt;
&lt;br /&gt;
== Contact ==&lt;br /&gt;
&lt;br /&gt;
Pour toute question sur ce module ou nos services :  &lt;br /&gt;
&lt;br /&gt;
[[Fichier:Siladel.png|link=https://www.siladel.fr|alt=Développeur web à Albi]]  &lt;br /&gt;
&lt;br /&gt;
* [https://www.siladel.fr/service/developpement-dolibarr Développement Dolibarr par SILADEL]  &lt;br /&gt;
* [https://www.dolistore.com/product.php?id=1190&amp;amp;title=addinventory&amp;amp;l=fr Module ADDINVENTORY disponible sur Dolistore]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Addinventory&amp;diff=533</id>
		<title>Addinventory</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Addinventory&amp;diff=533"/>
				<updated>2025-08-30T10:38:54Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : /* Page &amp;quot;Stocks référents&amp;quot; */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''ADDINVENTORY''' est un module Dolibarr qui permet de '''modifier et corriger rapidement vos stocks''' à partir d’une liste de produits, de lots ou de déclinaisons.  &lt;br /&gt;
&lt;br /&gt;
Principales fonctionnalités :  &lt;br /&gt;
* Correction en masse du stock à partir d’une liste (lots et déclinaisons inclus).  &lt;br /&gt;
* Création en masse de lots.  &lt;br /&gt;
* Gain de temps significatif lors des mouvements de stocks.  &lt;br /&gt;
* Tableau de suivi permettant un aperçu global des références en un coup d’œil.  &lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Compatible avec Dolibarr 6 et versions supérieures.  &lt;br /&gt;
&lt;br /&gt;
# Depuis l’interface Dolibarr, allez dans '''Configuration &amp;gt; Modules/Applications'''.  &lt;br /&gt;
# Cliquez sur l’onglet '''Déployer/Installer un module externe'''.  &lt;br /&gt;
&lt;br /&gt;
Une fois l’installation terminée, les pages '''Inventaire &amp;amp; correction''' et '''Stocks référents''' seront disponibles dans l’onglet '''Produits | Services'''.  &lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Conf addinventory2.png|880px]]  &lt;br /&gt;
&lt;br /&gt;
=== Activer les quantités décimales ===&lt;br /&gt;
Permet la gestion des stocks avec des valeurs décimales.  &lt;br /&gt;
&lt;br /&gt;
=== Correction par quantité Delta ===&lt;br /&gt;
Indiquez la quantité à ajouter ou à supprimer.  &lt;br /&gt;
Vous pouvez saisir directement une valeur (positive ou négative) ou utiliser les flèches pour ajuster la quantité.  &lt;br /&gt;
&lt;br /&gt;
=== Correction par substitution ===&lt;br /&gt;
Renseignez directement la quantité totale de produit disponible en stock.  &lt;br /&gt;
&lt;br /&gt;
=== Choix du mode (Delta ou Substitution) ===&lt;br /&gt;
Autorise les utilisateurs à basculer entre les deux méthodes dans la page '''Inventaire &amp;amp; correction'''.  &lt;br /&gt;
&lt;br /&gt;
=== Modification du stock des produits parents avec variantes ===&lt;br /&gt;
Par défaut, Dolibarr interdit la saisie de stock sur les produits parents à variantes.  &lt;br /&gt;
Cette option permet de forcer la correction dans certains cas spécifiques (ex. rattrapage d’erreurs).  &lt;br /&gt;
&lt;br /&gt;
=== Afficher les services ===&lt;br /&gt;
Inclut également les produits de type service dans les listes.  &lt;br /&gt;
&lt;br /&gt;
=== Activer la saisie du prix d’achat ===&lt;br /&gt;
Ajoute la possibilité de saisir le prix d’achat unitaire pour tous les produits nouvellement ajoutés.  &lt;br /&gt;
&lt;br /&gt;
=== Création de nouveaux lots ===&lt;br /&gt;
Pour les produits gérés en lots, cette option affiche directement les champs nécessaires :  &lt;br /&gt;
*n° de lot  &lt;br /&gt;
*entrepôt  &lt;br /&gt;
*DLC  &lt;br /&gt;
*DMD/DLUO  &lt;br /&gt;
*prix d’achat  &lt;br /&gt;
*stock  &lt;br /&gt;
&lt;br /&gt;
[[Fichier:Conf addinventory list.png|900px]]  &lt;br /&gt;
&lt;br /&gt;
== Fonctionnement de la correction du stock ==&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Doc_addinventory.png|880px]]  &lt;br /&gt;
&lt;br /&gt;
Pour modifier le stock d’un produit, indiquez soit la quantité totale disponible, soit un delta (en fonction du mode défini).  &lt;br /&gt;
&lt;br /&gt;
=== Mode quantité Delta ===&lt;br /&gt;
Saisissez une variation de stock (exemple : +10 ou -5).  &lt;br /&gt;
Cela ne remplace pas la valeur finale, mais ajuste le stock existant.  &lt;br /&gt;
&lt;br /&gt;
=== Mode Substitution ===&lt;br /&gt;
Saisissez directement la quantité totale disponible en stock.  &lt;br /&gt;
&lt;br /&gt;
Pour valider les modifications, cliquez sur le bouton '''Enregistrer''' en bas de page.  &lt;br /&gt;
&lt;br /&gt;
'''Important :''' lors d’une recherche filtrée par entrepôt, seuls les produits ayant un stock existant apparaissent. Pour afficher tous les produits, effectuez la recherche sans préciser d’entrepôt.  &lt;br /&gt;
&lt;br /&gt;
[[Fichier:Addinventory_screen04.jpg|880px]]  &lt;br /&gt;
&lt;br /&gt;
Chaque correction enregistre automatiquement un mouvement de stock dans Dolibarr, avec le delta de quantité (positif ou négatif), quelle que soit la méthode choisie.  &lt;br /&gt;
&lt;br /&gt;
== Contact ==&lt;br /&gt;
&lt;br /&gt;
Pour toute question sur ce module ou nos services :  &lt;br /&gt;
&lt;br /&gt;
[[Fichier:Siladel.png|link=https://www.siladel.fr|alt=Développeur web à Albi]]  &lt;br /&gt;
&lt;br /&gt;
* [https://www.siladel.fr/service/developpement-dolibarr Développement Dolibarr par SILADEL]  &lt;br /&gt;
* [https://www.dolistore.com/product.php?id=1190&amp;amp;title=addinventory&amp;amp;l=fr Module ADDINVENTORY disponible sur Dolistore]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Addinventory&amp;diff=532</id>
		<title>Addinventory</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Addinventory&amp;diff=532"/>
				<updated>2025-08-30T10:36:21Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''ADDINVENTORY''' est un module Dolibarr qui permet de '''modifier et corriger rapidement vos stocks''' à partir d’une liste de produits, de lots ou de déclinaisons.  &lt;br /&gt;
&lt;br /&gt;
Principales fonctionnalités :  &lt;br /&gt;
* Correction en masse du stock à partir d’une liste (lots et déclinaisons inclus).  &lt;br /&gt;
* Création en masse de lots.  &lt;br /&gt;
* Gain de temps significatif lors des mouvements de stocks.  &lt;br /&gt;
* Tableau de suivi permettant un aperçu global des références en un coup d’œil.  &lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Compatible avec Dolibarr 6 et versions supérieures.  &lt;br /&gt;
&lt;br /&gt;
# Depuis l’interface Dolibarr, allez dans '''Configuration &amp;gt; Modules/Applications'''.  &lt;br /&gt;
# Cliquez sur l’onglet '''Déployer/Installer un module externe'''.  &lt;br /&gt;
&lt;br /&gt;
Une fois l’installation terminée, les pages '''Inventaire &amp;amp; correction''' et '''Stocks référents''' seront disponibles dans l’onglet '''Produits | Services'''.  &lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Conf addinventory2.png|880px]]  &lt;br /&gt;
&lt;br /&gt;
=== Activer les quantités décimales ===&lt;br /&gt;
Permet la gestion des stocks avec des valeurs décimales.  &lt;br /&gt;
&lt;br /&gt;
=== Correction par quantité Delta ===&lt;br /&gt;
Indiquez la quantité à ajouter ou à supprimer.  &lt;br /&gt;
Vous pouvez saisir directement une valeur (positive ou négative) ou utiliser les flèches pour ajuster la quantité.  &lt;br /&gt;
&lt;br /&gt;
=== Correction par substitution ===&lt;br /&gt;
Renseignez directement la quantité totale de produit disponible en stock.  &lt;br /&gt;
&lt;br /&gt;
=== Choix du mode (Delta ou Substitution) ===&lt;br /&gt;
Autorise les utilisateurs à basculer entre les deux méthodes dans la page '''Inventaire &amp;amp; correction'''.  &lt;br /&gt;
&lt;br /&gt;
=== Modification du stock des produits parents avec variantes ===&lt;br /&gt;
Par défaut, Dolibarr interdit la saisie de stock sur les produits parents à variantes.  &lt;br /&gt;
Cette option permet de forcer la correction dans certains cas spécifiques (ex. rattrapage d’erreurs).  &lt;br /&gt;
&lt;br /&gt;
=== Afficher les services ===&lt;br /&gt;
Inclut également les produits de type service dans les listes.  &lt;br /&gt;
&lt;br /&gt;
=== Activer la saisie du prix d’achat ===&lt;br /&gt;
Ajoute la possibilité de saisir le prix d’achat unitaire pour tous les produits nouvellement ajoutés.  &lt;br /&gt;
&lt;br /&gt;
=== Création de nouveaux lots ===&lt;br /&gt;
Pour les produits gérés en lots, cette option affiche directement les champs nécessaires :  &lt;br /&gt;
*n° de lot  &lt;br /&gt;
*entrepôt  &lt;br /&gt;
*DLC  &lt;br /&gt;
*DMD/DLUO  &lt;br /&gt;
*prix d’achat  &lt;br /&gt;
*stock  &lt;br /&gt;
&lt;br /&gt;
[[Fichier:Conf addinventory list.png|900px]]  &lt;br /&gt;
&lt;br /&gt;
== Fonctionnement de la correction du stock ==&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Doc_addinventory.png|880px]]  &lt;br /&gt;
&lt;br /&gt;
Pour modifier le stock d’un produit, indiquez soit la quantité totale disponible, soit un delta (en fonction du mode défini).  &lt;br /&gt;
&lt;br /&gt;
=== Mode quantité Delta ===&lt;br /&gt;
Saisissez une variation de stock (exemple : +10 ou -5).  &lt;br /&gt;
Cela ne remplace pas la valeur finale, mais ajuste le stock existant.  &lt;br /&gt;
&lt;br /&gt;
=== Mode Substitution ===&lt;br /&gt;
Saisissez directement la quantité totale disponible en stock.  &lt;br /&gt;
&lt;br /&gt;
Pour valider les modifications, cliquez sur le bouton '''Enregistrer''' en bas de page.  &lt;br /&gt;
&lt;br /&gt;
'''Important :''' lors d’une recherche filtrée par entrepôt, seuls les produits ayant un stock existant apparaissent. Pour afficher tous les produits, effectuez la recherche sans préciser d’entrepôt.  &lt;br /&gt;
&lt;br /&gt;
[[Fichier:Addinventory_screen04.jpg|880px]]  &lt;br /&gt;
&lt;br /&gt;
Chaque correction enregistre automatiquement un mouvement de stock dans Dolibarr, avec le delta de quantité (positif ou négatif), quelle que soit la méthode choisie.  &lt;br /&gt;
&lt;br /&gt;
== Page &amp;quot;Stocks référents&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Addinventory screen03.jpg|880px]]  &lt;br /&gt;
&lt;br /&gt;
=== Stock physique ===&lt;br /&gt;
Quantité réellement disponible dans l’entrepôt.  &lt;br /&gt;
&lt;br /&gt;
=== Stock virtuel ===&lt;br /&gt;
Quantité projetée après prise en compte des opérations en cours (réceptions fournisseurs, expéditions clients, etc.).  &lt;br /&gt;
&lt;br /&gt;
=== Qty commandes clients ===&lt;br /&gt;
Quantité engagée dans les commandes clients ouvertes.  &lt;br /&gt;
&lt;br /&gt;
=== Qty factures clients ===&lt;br /&gt;
Quantité engagée dans les factures clients ouvertes.  &lt;br /&gt;
&lt;br /&gt;
== Contact ==&lt;br /&gt;
&lt;br /&gt;
Pour toute question sur ce module ou nos services :  &lt;br /&gt;
&lt;br /&gt;
[[Fichier:Siladel.png|link=https://www.siladel.fr|alt=Développeur web à Albi]]  &lt;br /&gt;
&lt;br /&gt;
* [https://www.siladel.fr/service/developpement-dolibarr Développement Dolibarr par SILADEL]  &lt;br /&gt;
* [https://www.dolistore.com/product.php?id=1190&amp;amp;title=addinventory&amp;amp;l=fr Module ADDINVENTORY disponible sur Dolistore]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Viewmap&amp;diff=531</id>
		<title>Viewmap</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Viewmap&amp;diff=531"/>
				<updated>2025-08-30T10:34:49Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le module '''Viewmap''' permet de '''géolocaliser vos tiers''' (prospects, clients, fournisseurs, contacts et adhérents) directement sur une carte Google Maps.  &lt;br /&gt;
Lors de la création d’un nouveau tiers, son adresse est automatiquement géolocalisée. Vous pouvez ainsi afficher l’ensemble de vos tiers sur une seule et même carte.  &lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
# Depuis l’interface Dolibarr, rendez-vous dans '''Configuration &amp;gt; Modules/Applications'''.  &lt;br /&gt;
# Cliquez sur l’onglet '''Déployer/Installer un module externe'''.  &lt;br /&gt;
# Une fois l’installation terminée, ouvrez la page de configuration du module et saisissez votre '''clé API Google Maps'''.  &lt;br /&gt;
&lt;br /&gt;
La carte sera ensuite accessible depuis l’onglet '''Outils''', ainsi que depuis les fiches de vos tiers.  &lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
Après installation, activez le module depuis '''Configuration &amp;gt; Modules/Applications'''.  &lt;br /&gt;
&lt;br /&gt;
[[Fichier:Viewmap index.jpg|900px]]  &lt;br /&gt;
[[Fichier:Viewmap screen config.jpg|900px]]  &lt;br /&gt;
&lt;br /&gt;
=== Test du géocodage lors de la création d’un tiers ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Vous pouvez tester la géolocalisation d’une adresse postale directement lors de la création d’un nouveau tiers grâce à l’option&lt;br /&gt;
« Test du géocodage pendant le processus de création ».&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
=== Clé API Google Maps ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;&lt;br /&gt;
Pour afficher les cartes Google Maps dans Dolibarr, vous devez renseigner une clé API valide.&lt;br /&gt;
Ce tutoriel vous explique comment l’obtenir et l’intégrer au module Viewmap.&lt;br /&gt;
Un compte Gmail est requis pour générer cette clé.&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
=== Niveau de zoom des cartes ===&lt;br /&gt;
&lt;br /&gt;
Vous pouvez ajuster le zoom sur la fiche client et sur la carte générale :  &lt;br /&gt;
* 1 = vue monde  &lt;br /&gt;
* 6 = pays (France entière)  &lt;br /&gt;
* 11 = département  &lt;br /&gt;
* 16 = quartier  &lt;br /&gt;
&lt;br /&gt;
=== Clusterisation des marqueurs ===&lt;br /&gt;
&lt;br /&gt;
Le module propose une fonction de '''regroupement automatique des marqueurs''' lorsque plusieurs tiers sont situés dans la même zone.  &lt;br /&gt;
&lt;br /&gt;
=== Géocodage en masse ===&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Geocodage_setting.png]]  &lt;br /&gt;
&lt;br /&gt;
Chaque clic sur le bouton '''« Géocoder »''' permet de traiter 100 adresses à la fois.  &lt;br /&gt;
Répétez l’opération jusqu’à ce que l’ensemble de vos tiers soit géolocalisé.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;&lt;br /&gt;
L’API Google Geocoding est limitée à 2 500 requêtes de géolocalisation par jour.&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
=== Suppression des données de géocodage ===&lt;br /&gt;
&lt;br /&gt;
Vous pouvez réinitialiser les coordonnées GPS de tous vos tiers et contacts via l’option '''Effacer les données de géocodage'''.  &lt;br /&gt;
&lt;br /&gt;
=== Personnalisation des marqueurs ===&lt;br /&gt;
&lt;br /&gt;
Le module permet de définir vos propres marqueurs en fonction du type de tiers.  &lt;br /&gt;
Il est recommandé d’utiliser des images au format '''PNG, GIF ou JPG''', d’une taille maximale de '''48 px'''.  &lt;br /&gt;
&lt;br /&gt;
[[Fichier:Viewmap marqueurs.jpg]]  &lt;br /&gt;
&lt;br /&gt;
== Obtenir une clé API Google Maps ==&lt;br /&gt;
&lt;br /&gt;
Rendez-vous sur [https://console.developers.google.com console.developers.google.com].  &lt;br /&gt;
&lt;br /&gt;
=== 1. Création d’un projet ===&lt;br /&gt;
&lt;br /&gt;
Lors de votre première connexion, un projet par défaut « My Project » sera créé.  &lt;br /&gt;
Cochez simplement :  &lt;br /&gt;
* Recevoir ou non l’actualité Google APIs.  &lt;br /&gt;
* Accepter les conditions d’utilisation.  &lt;br /&gt;
&lt;br /&gt;
=== 2. Génération de la clé ===&lt;br /&gt;
&lt;br /&gt;
* Donnez un nom à la clé (par défaut : « Clé API 1 »).  &lt;br /&gt;
* Sécurisez-la en restreignant son usage à l’'''adresse IP de votre serveur Dolibarr'''.  &lt;br /&gt;
* Activez les API nécessaires :  &lt;br /&gt;
** '''Maps JavaScript API'''  &lt;br /&gt;
** '''Geocoding API'''  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;&lt;br /&gt;
Depuis le 11 juin 2018, l’activation d’un compte de facturation est obligatoire.&lt;br /&gt;
Cependant, Google propose un crédit gratuit mensuel couvrant la majorité des usages courants.&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;&lt;br /&gt;
Important : le module Viewmap utilise l’API de géocodage uniquement lors de la première géolocalisation d’une adresse.&lt;br /&gt;
&amp;lt;/pre&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
Cliquez ensuite sur '''Créer'''.  &lt;br /&gt;
&lt;br /&gt;
=== 3. Récupération de la clé ===&lt;br /&gt;
&lt;br /&gt;
Une fenêtre s’affiche avec votre clé API. Copiez-la et collez-la dans la configuration du module Viewmap.  &lt;br /&gt;
&lt;br /&gt;
== Utilisation ==&lt;br /&gt;
&lt;br /&gt;
=== Carte intégrée à la fiche d’un tiers ===&lt;br /&gt;
&lt;br /&gt;
Lors de la saisie d’une adresse, vous pouvez la géocoder directement depuis la fiche du tiers.  &lt;br /&gt;
&lt;br /&gt;
[[Fichier:Viewmaptier.jpg|700px]]  &lt;br /&gt;
&lt;br /&gt;
=== Options d’affichage ===&lt;br /&gt;
&lt;br /&gt;
Avec l’API Viewmap, vous pouvez choisir de masquer certaines informations (e-mail, téléphone, URL) ou de les afficher selon vos besoins.  &lt;br /&gt;
&lt;br /&gt;
[[Fichier:Viewmap option api.jpg|900px]]  &lt;br /&gt;
&lt;br /&gt;
=== Carte globale des tiers ===&lt;br /&gt;
&lt;br /&gt;
Depuis le menu '''Outils''', vous accédez à une carte regroupant l’ensemble de vos tiers.  &lt;br /&gt;
Des filtres permettent de restreindre l’affichage par :  &lt;br /&gt;
* Type de tiers  &lt;br /&gt;
* Pays  &lt;br /&gt;
* Département  &lt;br /&gt;
* Catégorie  &lt;br /&gt;
* Commercial associé  &lt;br /&gt;
&lt;br /&gt;
[[Fichier:Viewmap map2.jpg|900px]]  &lt;br /&gt;
&lt;br /&gt;
== Contact ==&lt;br /&gt;
&lt;br /&gt;
Pour toute question concernant ce module ou nos services :  &lt;br /&gt;
&lt;br /&gt;
[[Fichier:Siladel.png|link=https://www.siladel.fr|alt=Développeur web à Albi]]  &lt;br /&gt;
&lt;br /&gt;
* [https://www.siladel.fr/service/developpement-dolibarr Développement Dolibarr par SILADEL]  &lt;br /&gt;
* [https://www.dolistore.com/product.php?id=1398&amp;amp;title=viewmap&amp;amp;l=fr Module Viewmap disponible sur Dolistore]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Liste_de_nos_modules&amp;diff=530</id>
		<title>Liste de nos modules</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Liste_de_nos_modules&amp;diff=530"/>
				<updated>2025-08-30T10:30:43Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : a&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Modules Dolibarr ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;0&amp;quot; style=&amp;quot;border-collapse:collapse&amp;quot;&lt;br /&gt;
| [[Fichier:addremise_box.png|160px|thumb|left|link=Addremise|Ajoutez des remises facilement]]&lt;br /&gt;
| [[Fichier:viewmap_box.png|160px|thumb|left|link=Viewmap|Afffichez une carte de tous vos contacts]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Fichier:exportpresta_box.png|160px|thumb|left|link=Exportpresta|Exportez vos produits sur PrestShop]]&lt;br /&gt;
| [[Fichier:jaquette_addinventory.png|160px|thumb|left|link=Addinventory|Corrigez votre stock facilement]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Fichier:modEANPRODOC.png|160px|thumb|left|link=Eanprodoc|Afficher les codes-barres de vos produits dans vos documents PDF]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Modules Prestashop 1.6 &amp;amp; 1.8 ==&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;0&amp;quot; style=&amp;quot;border-collapse:collapse&amp;quot;&lt;br /&gt;
| [[Fichier:dolistock_box.png|256px|thumb|left|link=Dolistock|Synchronisez votre stock entre Dolibarr et PrestaShop]]&lt;br /&gt;
| [[Fichier:256px-bestdefaultcombination_box.png|256px|thumb|left|link=best default combination|Module Remplacer automatiquement vos déclinaisons par défaut avec stratégie]]&lt;br /&gt;
| [[Fichier:256px-bypassinvoice_box.png|256px|thumb|left|link=Bypassinvoice|Déléguer la gestion des vos factures Prestashop à Dolibarr]]&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Contact ==&lt;br /&gt;
&lt;br /&gt;
Pour toutes questions sur les produits et services, veuillez nous contacter:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Siladel.png|link=https://www.siladel.fr|Développement e-commerce sur mesure]]&lt;br /&gt;
&lt;br /&gt;
[https://www.dolistore.com/index.php?controller=search&amp;amp;search_query=siladel&amp;amp;submit_search= Catalogue de nos modules disponibles à l’achat pour Dolibarr]&lt;br /&gt;
&lt;br /&gt;
[https://www.siladel.fr/service/infogerance TMA de vos applications Web]&lt;br /&gt;
&lt;br /&gt;
[https://www.siladel.fr/service/developpement-sur-mesure Développement web sur mesure]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Liste_de_nos_modules&amp;diff=529</id>
		<title>Liste de nos modules</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Liste_de_nos_modules&amp;diff=529"/>
				<updated>2025-08-30T10:25:21Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : /* Contact */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Modules Dolibarr ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;0&amp;quot; style=&amp;quot;border-collapse:collapse&amp;quot;&lt;br /&gt;
| [[Fichier:addremise_box.png|160px|thumb|left|link=Addremise|Ajoutez des remises facilement]]&lt;br /&gt;
| [[Fichier:viewmap_box.png|160px|thumb|left|link=Viewmap|Afffichez une carte de tous vos contacts]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Fichier:exportpresta_box.png|160px|thumb|left|link=Exportpresta|Exportez vos produits sur PrestShop]]&lt;br /&gt;
| [[Fichier:jaquette_addinventory.png|160px|thumb|left|link=Addinventory|Corrigez votre stock facilement]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Fichier:modEANPRODOC.png|160px|thumb|left|link=Eanprodoc|Afficher les codes-barres de vos produits dans vos documents PDF]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Modules Prestashop 1.6 &amp;amp; 1.8 ==&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;0&amp;quot; style=&amp;quot;border-collapse:collapse&amp;quot;&lt;br /&gt;
| [[Fichier:dolistock_box.png|256px|thumb|left|link=Dolistock|Synchronisez votre stock entre Dolibarr et PrestaShop]]&lt;br /&gt;
| [[Fichier:256px-bestdefaultcombination_box.png|256px|thumb|left|link=best default combination|Module Remplacer automatiquement vos déclinaisons par défaut avec stratégie]]&lt;br /&gt;
| [[Fichier:256px-bypassinvoice_box.png|256px|thumb|left|link=Bypassinvoice|Déléguer la gestion des vos factures Prestashop à Dolibarr]]&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Contact ==&lt;br /&gt;
&lt;br /&gt;
Pour toutes questions sur les produits et services, veuillez nous contacter:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Siladel.png|link=https://www.siladel.fr|développement e-commerce sur mesure]]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Liste_de_nos_modules&amp;diff=528</id>
		<title>Liste de nos modules</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Liste_de_nos_modules&amp;diff=528"/>
				<updated>2025-08-30T10:24:44Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : /* Contact */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Modules Dolibarr ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;0&amp;quot; style=&amp;quot;border-collapse:collapse&amp;quot;&lt;br /&gt;
| [[Fichier:addremise_box.png|160px|thumb|left|link=Addremise|Ajoutez des remises facilement]]&lt;br /&gt;
| [[Fichier:viewmap_box.png|160px|thumb|left|link=Viewmap|Afffichez une carte de tous vos contacts]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Fichier:exportpresta_box.png|160px|thumb|left|link=Exportpresta|Exportez vos produits sur PrestShop]]&lt;br /&gt;
| [[Fichier:jaquette_addinventory.png|160px|thumb|left|link=Addinventory|Corrigez votre stock facilement]]&lt;br /&gt;
|-&lt;br /&gt;
| [[Fichier:modEANPRODOC.png|160px|thumb|left|link=Eanprodoc|Afficher les codes-barres de vos produits dans vos documents PDF]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Modules Prestashop 1.6 &amp;amp; 1.8 ==&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;0&amp;quot; style=&amp;quot;border-collapse:collapse&amp;quot;&lt;br /&gt;
| [[Fichier:dolistock_box.png|256px|thumb|left|link=Dolistock|Synchronisez votre stock entre Dolibarr et PrestaShop]]&lt;br /&gt;
| [[Fichier:256px-bestdefaultcombination_box.png|256px|thumb|left|link=best default combination|Module Remplacer automatiquement vos déclinaisons par défaut avec stratégie]]&lt;br /&gt;
| [[Fichier:256px-bypassinvoice_box.png|256px|thumb|left|link=Bypassinvoice|Déléguer la gestion des vos factures Prestashop à Dolibarr]]&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Contact ==&lt;br /&gt;
&lt;br /&gt;
Pour toutes questions sur les produits et services, veuillez nous contacter:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Siladel.png|link=https://www.siladel.fr/service/developpement-sur-mesure|développeur e-commerce sur mesure]]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Bypassinvoice&amp;diff=527</id>
		<title>Bypassinvoice</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Bypassinvoice&amp;diff=527"/>
				<updated>2025-08-30T10:23:12Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : /* Contact */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
&lt;br /&gt;
BypassInvoice permet de déléguer la gestion et la numérotation des factures&lt;br /&gt;
PrestaShop à Dolibarr, simplifiant la facturation et la synchronisation des données, et&lt;br /&gt;
offrant une solution efficace pour les commerçants cherchant à optimiser leurs&lt;br /&gt;
processus comptables et à offrir une meilleure expérience client.&lt;br /&gt;
&lt;br /&gt;
==Fonctionnement du module :==&lt;br /&gt;
&lt;br /&gt;
Les factures, les clients (tiers), les adresses de facturation et les paiements sont&lt;br /&gt;
automatiquement générés dans Dolibarr dès qu'une commande est réglée sur PrestaShop. Pour les paiements effectués par chèque, la création de la facture&lt;br /&gt;
dans Dolibarr est déclenchée automatiquement une fois que le statut de la commande est mis à jour comme &amp;quot;paiement accepté&amp;quot;. &lt;br /&gt;
Les tiers sont créés uniquement si le n° de siret ou l'adresse e-mail n'est pas déjà présente dans Dolibarr. &lt;br /&gt;
Si un n° de siret ou un e-mail existe déjà, une mise à jour du tiers sera effectuée avec les informations fournies.&lt;br /&gt;
&lt;br /&gt;
A propos des produits, BypassInvoice procède initialement à une vérification des similitudes au niveau des codes-barres EAN13; en l'absence de correspondance, il passe ensuite à la vérification de la référence du produit. Si aucun produit n'est identifié, les entrées correspondantes de vos lignes de produit sur la facture Dolibarr seront affichées en caractères gras.&lt;br /&gt;
&lt;br /&gt;
Avec le modue Duo, Le module se contente de générer une facture dans Dolibarr avant de&lt;br /&gt;
transférer le numéro de facture vers PrestaShop, permettant ainsi à ce dernier de produire sa propre facture dans son format spécifique.&lt;br /&gt;
&lt;br /&gt;
== Fonctionnalités ==&lt;br /&gt;
&lt;br /&gt;
*Deux modes de fonctionnement : Mode Exclusif pour une gestion complète des factures via Dolibarr et Mode Duo pour la gestion des numéros de facture en synchronisation avec PrestaShop&lt;br /&gt;
*Automatisation de la création de factures/avoir dans Dolibarr à la suite des commandes payées sur PrestaShop.&lt;br /&gt;
*Automatisation de la création des tiers dans Dolibarr à la suite des commandes payées sur PrestaShop.&lt;br /&gt;
*Automatisation de la création des adresses de facturation dans Dolibarr à la suite des commandes payées sur PrestaShop.&lt;br /&gt;
*Gestion des paiements différés permettant la création de factures sans paiement immédiat.&lt;br /&gt;
*Synchronisation des numéros de facture entre PrestaShop et Dolibarr pour une cohérence comptable.&lt;br /&gt;
*Personnalisation de l'affichage des factures dans l'espace client PrestaShop.&lt;br /&gt;
&lt;br /&gt;
== Prérequis ==&lt;br /&gt;
*PrestaShop : Version compatible (e.g., 1.7.x ou supérieure).&lt;br /&gt;
*Dolibarr : Version compatible (e.g., 14.x ou supérieure) avec un accès API configuré.&lt;br /&gt;
*Droits d'Administration : Accès administrateur sur PrestaShop et Dolibarr.&lt;br /&gt;
&lt;br /&gt;
*chaque entité tierce doit posséder au minimum une adresse e-mail unique. Lorsque BypassInvoice effectue une recherche de tiers dans Dolibarr, il procède d'abord par la vérification du numéro de SIRET avant de se baser sur l'adresse e-mail. si aucun tiers correspondant n'est trouvé, un nouveau tiers est alors créé dans Dolibarr.&lt;br /&gt;
&lt;br /&gt;
*Pour effectuer une décrémentation de vos stocks avec Dolibarr, le code-barres ou la référence produit doit correspondre exactement entre Dolibarr et PrestaShop.&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
*Téléchargez le fichier d'installation du module BypassInvoice.&lt;br /&gt;
*Connectez-vous à votre espace administrateur PrestaShop.&lt;br /&gt;
*Accédez à &amp;quot;Modules&amp;quot; &amp;gt; &amp;quot;Module Manager&amp;quot; et sélectionnez &amp;quot;Télécharger un module&amp;quot;.&lt;br /&gt;
*Sélectionnez le fichier d'installation et laissez le module s'installer automatiquement. *Activez le module depuis votre tableau de bord.&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
Après avoir installé le module BypassInvoice, vous devez le configurer pour qu'il&lt;br /&gt;
fonctionne correctement avec votre instance Dolibarr. Voici un aperçu détaillé des&lt;br /&gt;
options disponibles dans la configuration du module :&lt;br /&gt;
&lt;br /&gt;
'''Mode Exclusif'''&lt;br /&gt;
*Désactivez la fonction de facturation native de PrestaShop. Il suffit de se rendre dans la page Factures dans le menu de gauche de la section Commandes&lt;br /&gt;
*Configurez le module pour transférer toutes les opérations de facturation à Dolibarr.&lt;br /&gt;
*Personnalisez l'affichage des factures de l'espace client de PrestaShop.&lt;br /&gt;
&lt;br /&gt;
''' Mode Duo '''&lt;br /&gt;
*Vous maintenez la création de factures dans PrestaShop.&lt;br /&gt;
*Configurez le module pour transférer toutes les opérations de facturation à Dolibarr.&lt;br /&gt;
*Configurez le format du numéro de facture pour qu'il soit identique entre Dolibarr et PrestaShop.&lt;br /&gt;
&lt;br /&gt;
Le module se contente de générer une facture dans Dolibarr avant de transférer le numéro de facture vers PrestaShop, permettant ainsi à ce dernier de produire sa propre facture dans son format spécifique.&lt;br /&gt;
&lt;br /&gt;
== Options Détaillées ==&lt;br /&gt;
'''BypassInvoice'''&lt;br /&gt;
*Activer ou désactiver le module : Cette option vous permet de mettre en service ou de suspendre temporairement la fonctionnalité de BypassInvoice sans avoir à désinstaller le module. Même lorsque le module est désactivé, vos clients continueront d'avoir accès à leur historique de factures dans leur espace client. Cette approche permet une flexibilité dans la gestion du module tout en préservant la continuité de l'expérience utilisateur.&lt;br /&gt;
&lt;br /&gt;
'''Logs des erreurs'''&lt;br /&gt;
*Gérer l'activation des logs : Activez cette option pour enregistrer les erreurs et les opérations importantes dans un fichier de log. Cela peut être crucial pour le débogage et la maintenance du système. Les fichiers de log sont stockés dans /modules/bypassinvoice/logs. Pour une consultation rapide, un lien direct vers le fichier de journal est mis à disposition en haut de la page de configuration du module.&lt;br /&gt;
&lt;br /&gt;
'''Clé API'''&lt;br /&gt;
*Saisissez la clé API de votre instance Dolibarr : La clé API est essentielle pour authentifier et autoriser les communications sécurisées entre PrestaShop et Dolibarr. Vous devez générer cette clé dans votre instance Dolibarr et la saisir ici.&lt;br /&gt;
&lt;br /&gt;
'''URL'''&lt;br /&gt;
*URL de votre instance Dolibarr : Indiquez l'URL complète où votre Dolibarr est installé. Cette information permet au module BypassInvoice de se connecter correctement à Dolibarr pour la transmission des données.&lt;br /&gt;
&lt;br /&gt;
'''ENTITÉ'''&lt;br /&gt;
*Entité Dolibarr concernée : Si vous utilisez Dolibarr gère plusieurs sociétés, précisez ici l'identifiant de l'entité concernée par les opérations du module. Par défaut, ce paramètre est fixé à 1.&lt;br /&gt;
&lt;br /&gt;
'''Paiement CB'''&lt;br /&gt;
*Correspondance de paiement par carte bancaire avec Dolibarr : Configurez cette option pour associer les paiements par carte de crédit réalisés sur PrestaShop avec le type de paiement correspondant dans Dolibarr. &lt;br /&gt;
&lt;br /&gt;
'''BANQUE'''&lt;br /&gt;
*Banque de destination pour les paiements : Sélectionnez la banque au sein de Dolibarr où les paiements effectués sur PrestaShop devraient être enregistrés. Cette option est utile pour assurer que les transactions sont correctement affectées dans votre comptabilité Dolibarr.&lt;br /&gt;
&lt;br /&gt;
'''Entrepôt'''&lt;br /&gt;
*Sélection de l'entrepôt par défaut pour la gestion des stocks : Déterminez et forcer quel entrepôt dans Dolibarr sera utilisé pour la déduction automatique des stocks à la suite des ventes réalisées sur PrestaShop. Cette configuration aide à maintenir une synchronisation précise des niveaux de stock entre les deux systèmes. Veillez à ce que les références des produits soient identiques entre Dolibarr et PrestaShop. BypassInvoice procède initialement à une vérification des similitudes au niveau des codes-barres EAN13; en l'absence de correspondance, il passe ensuite à la vérification de la référence du produit.&lt;br /&gt;
&lt;br /&gt;
'''Facture d’avoir'''&lt;br /&gt;
*Activer ou désactiver les avoirs exclusivement pour les produits. (autorise la création d'avoir et leur envoi vers Dolibarr).&lt;br /&gt;
&lt;br /&gt;
=== Bloc Compte de Facturation ===&lt;br /&gt;
(présent seulement après avoir désactivé la facturation Prestashop)&lt;br /&gt;
&lt;br /&gt;
'''Afficher les factures Dolibarr'''&lt;br /&gt;
* Intègre un bloc pour les factures Dolibarr dans l'espace client PrestaShop.&lt;br /&gt;
&lt;br /&gt;
'''Afficher toutes les factures Dolibarr'''&lt;br /&gt;
*Choix entre afficher toutes les factures ou seulement celles liées à des commandes PrestaShop.&lt;br /&gt;
&lt;br /&gt;
'''Titre de la page et du bloc de l'espace client'''&lt;br /&gt;
*Personnalisation du titre pour le bloc des factures (ex : &amp;quot;Factures&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
'''Modèle PDF de facture'''&lt;br /&gt;
*Sélection du modèle PDF pour les factures générées par Dolibarr (ex : &amp;quot;crabe&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
=== Personnalisation du Numéro de Facture ===&lt;br /&gt;
(Options pour le Mode Duo)&lt;br /&gt;
&lt;br /&gt;
Ces options offrent une flexibilité significative dans la personnalisation du format des numéros de facture générés dans le cadre du mode Duo de BypassInvoice, assurant que la numérotation s'aligne précisément avec les besoins comptables et de suivi spécifiques de l'entreprise.&lt;br /&gt;
&lt;br /&gt;
'''Année dans le numéro de facture'''&lt;br /&gt;
*Activée : Intègre l'année courante dans le numéro de facture pour faciliter le suivi chronologique.&lt;br /&gt;
*Désactivée : Omet l'année du format du numéro de facture pour une numérotation plus concise.&lt;br /&gt;
&lt;br /&gt;
'''Présence du Mois dans le Numéro de Facture'''&lt;br /&gt;
*Activée : Ajoute le mois en cours au numéro de facture, offrant une granularité temporelle supplémentaire.&lt;br /&gt;
*Désactivée : Exclut le mois pour simplifier le numéro de facture.&lt;br /&gt;
&lt;br /&gt;
'''Date Courte'''&lt;br /&gt;
*Activée : Utilise une représentation abrégée de la date (par exemple, &amp;quot;2401&amp;quot; pour le 24 janvier) dans le numéro de facture.&lt;br /&gt;
*Désactivée : Préfère un format de numérotation sans spécification de date détaillée.&lt;br /&gt;
&lt;br /&gt;
'''Caractère de Séparation'''&lt;br /&gt;
*Séparateur entre la Date et le Numéro de Facture : Permet de définir un caractère spécifique (tel qu'un tiret, un point ou un slash) pour séparer les éléments de la date du reste du numéro de facture, améliorant ainsi la lisibilité.&lt;br /&gt;
&lt;br /&gt;
'''Longueur du Numéro de Facture'''&lt;br /&gt;
*Définition de la Longueur du Numéro : Spécifiez la longueur totale du numéro de facture, permettant une standardisation et une cohérence, surtout pour l'alignement des systèmes de classement et de stockage des factures.&lt;br /&gt;
&lt;br /&gt;
=== Paramètres des Factures avec Paiements Différés ===&lt;br /&gt;
&lt;br /&gt;
'''Statut sans paiement'''&lt;br /&gt;
Configurez le statut attribué aux commandes qui ne requièrent pas de&lt;br /&gt;
paiement immédiat. Lorsqu'un client opte pour un mode de paiement dont le statut est défini ici, aucun enregistrement de paiement ne sera transmis à Dolibarr, même si le statut de la commande évolue vers un état indiquant que le paiement a été accepté.&lt;br /&gt;
&lt;br /&gt;
'''Conditions de paiement attribuées pour ce statut'''&lt;br /&gt;
Spécifiez les modalités de paiement qui doivent être appliquées aux commandes identifiées par un statut indiquant un paiement différé. Assurez-vous que ces modalités sont alignées sur les options de paiement&lt;br /&gt;
préalablement établies dans Dolibarr. Une facture générée sous ce statut spécifique utilisera exclusivement ces conditions de paiement déterminées.&lt;br /&gt;
&lt;br /&gt;
== Contact ==&lt;br /&gt;
&lt;br /&gt;
Pour toutes questions sur les produits et services, veuillez nous contacter:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Siladel.png|link=https://www.siladel.fr|alt=développeur prestashop]]&lt;br /&gt;
&lt;br /&gt;
[https://www.siladel.fr/service/developpement-prestashop Développeur Prestashop]&lt;br /&gt;
&lt;br /&gt;
[https://www.dolistore.com/product.php?id=401&amp;amp;title=bypassinvoice&amp;amp;l=fr Module Bypassinvoice disponible sur Dolistore]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Dolistock&amp;diff=526</id>
		<title>Dolistock</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Dolistock&amp;diff=526"/>
				<updated>2025-08-30T10:22:12Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : /* Contact */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
Ce module s’adresse à tous ceux qui souhaitent synchroniser le stock entre Dolibarr et Prestashop.&lt;br /&gt;
&lt;br /&gt;
Dolistock a été créé par [https://www.siladel.fr/ Siladel : Développeur Prestashop Albi] pour répondre à un besoin précis, une gestion fine des mouvements de stocks entre Dolibarr et PrestaShop..&lt;br /&gt;
&lt;br /&gt;
Sa particularité réside dans la sélection des produits a traiter et de prendre en compte une sélection de produit basé sur un type de référence (ID, REF, EAN13, UPC, ISBN).&lt;br /&gt;
&lt;br /&gt;
Concernant Dolibarr, les mouvements de stock générés par le module apparaissent de façon claire et précise.&lt;br /&gt;
&lt;br /&gt;
==Fonctionnement du module Dolistock :==&lt;br /&gt;
&lt;br /&gt;
===Synchronisation de Prestashop vers Dolibarr en temps réel===&lt;br /&gt;
&lt;br /&gt;
*Les articles expédiés décrémentent votre stock prestashop et celui de Dolibarr. &lt;br /&gt;
*Les retours d'articles incrémentent votre stock Prestashop et celui de Dolibarr. &lt;br /&gt;
*Les corrections de stocks effectuées sous prestashop '''ne sont pas synchonisées''' vers Dolibarr.&lt;br /&gt;
*La synchronisation des articles se fait de Prestashop vers Dolibarr pour l'entrepôt et les catégories sélectionnées uniquement. &lt;br /&gt;
*L'identifiant choisi doit correspondre sur Prestashop et Dolibarr. (Seuls, les articles ayant une similitude seront synchronisés).&lt;br /&gt;
&lt;br /&gt;
===Synchronisation de Dolibarr vers Prestashop===&lt;br /&gt;
&lt;br /&gt;
*La synchronisation des stocks de Dolibarr vers Prestashop se fait à l'aide d'une tâche CRON&lt;br /&gt;
*La synchronisation des stocks vers Prestashop se fait uniquement à partir de l'entrepôt et des catégories sélectionnées.&lt;br /&gt;
*La synchronisation peut se faire sur les produits en ventes ou pas (produits tagués en vente sur la fiche produit de Dolibarr).&lt;br /&gt;
*La synchronisation se fait uniquement sur les produits dont la quantité a été mise à jour.&lt;br /&gt;
*Les produits venant de Dolibarr sans stock ou avec stocks négatifs ou nuls seront enregistrés 0 stock sur Prestashop.&lt;br /&gt;
&lt;br /&gt;
==Installation==&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Conf01.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Entrez dans le back-office de Prestashop (la partie administration du site).&lt;br /&gt;
&lt;br /&gt;
Sur les onglets situés à gauche, cliquez sur &amp;quot;Modules&amp;quot; puis la page &amp;quot;modules et services&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Cliquez sur le bouton &amp;quot;Installer un module&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Faites glisser le fichier zip dans le cadre.&lt;br /&gt;
&lt;br /&gt;
Terminez l'installation en appuyant sur &amp;quot;Configurer&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Description des fonctions==&lt;br /&gt;
&lt;br /&gt;
[[Fichier:conf02.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''LOGS :'''&lt;br /&gt;
&lt;br /&gt;
Activer ou non les logs du module. Les fichiers logs se trouvent à la racine de PrestaShop dans le dossier app/logs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''CLE :'''&lt;br /&gt;
&lt;br /&gt;
Clé de l’Api générée à partir de Dolibarr. (cette clé se trouve sur la fiche utilisateur de Dolibarr).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''URL :'''&lt;br /&gt;
&lt;br /&gt;
Adresse du site Dolibarr , (Ex:  monsite.fr ou monsite.fr/htdocs)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Identifiant produit :'''&lt;br /&gt;
&lt;br /&gt;
Choisissez un identifiant similaire entre Dolibarr et PrestaShop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Entrepôt :'''&lt;br /&gt;
&lt;br /&gt;
Sélectionner l’entrepôt à synchroniser&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Stock négatif :'''&lt;br /&gt;
&lt;br /&gt;
Permet de recevoir des mouvements de stock PrestaShop vers Dolibarr alors que le produit se trouve&lt;br /&gt;
en rupture sur Dolibarr. (reprenez la même configuration de Dolibarr pour éviter de générer un&lt;br /&gt;
message d’alerte). cette fonction se trouve dans le module '''stock''' de Dolibarr (Règles d'exigence sur les stocks)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Catégorie :'''&lt;br /&gt;
&lt;br /&gt;
Sélectionnez 1 ou plusieurs catégories à l’aide de la touche CTRL.&lt;br /&gt;
&lt;br /&gt;
Seul les produits des catégories sélectionnées seront pris en compte lors de la synchronisation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Zone de mise à jour du stock manuellement :===&lt;br /&gt;
&lt;br /&gt;
Une fois la configuration du module terminée, vous pourrez lancer une mise à jour de vos stocks manuellement. &lt;br /&gt;
&lt;br /&gt;
A la fin de l’opération, le module vous indique le nombre de produits traités.&lt;br /&gt;
&lt;br /&gt;
Recommencez l’opération tant que le module vous retourne un nombre positif.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Produits en ventes :'''&lt;br /&gt;
&lt;br /&gt;
N’autorise que les produits tagués &amp;quot;en vente&amp;quot; sur Dolibarr et exclut le reste.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Tâche CRON'''&lt;br /&gt;
&lt;br /&gt;
Il s’agit de déclencher une tâche routinière d’administration système à une heure précise.&lt;br /&gt;
&lt;br /&gt;
Dolistock fournit un lien en bas de page permettant de synchroniser les stocks Dolibarr vers Prestashop. &lt;br /&gt;
Ce lien peut être copié dans votre gestionnaire de tâches planifiées Dolibarr sinon utiliser un service externe pour gérer vos tâches CRON.&lt;br /&gt;
&lt;br /&gt;
Également, le lien peut être généré avec le module par défaut '''Cron Jobs''' de PrestaShop.&lt;br /&gt;
&lt;br /&gt;
Dolibarr autorise la saisie de tâches CRON. Pour cela, activer le module « Travaux programmés » puis créer un « nouveau travail&lt;br /&gt;
planifié ». Ensuite, saisissez l’URL de la tâche CRON à la ligne « commande » et pour finir, configurez la fréquence d’exécution.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Contact ==&lt;br /&gt;
&lt;br /&gt;
Pour toutes questions sur les produits et services, veuillez nous contacter:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Siladel.png|link=https://www.siladel.fr|alt=développeur prestashop]]&lt;br /&gt;
&lt;br /&gt;
[https://www.siladel.fr/service/developpement-prestashop Développeur Prestashop]&lt;br /&gt;
&lt;br /&gt;
[https://www.dolistore.com/product.php?id=1365&amp;amp;title=dolistock&amp;amp;l=fr Module Dolistock disponible sur Dolistore]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Dolistock&amp;diff=525</id>
		<title>Dolistock</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Dolistock&amp;diff=525"/>
				<updated>2025-08-30T10:21:49Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : /* Contact */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
Ce module s’adresse à tous ceux qui souhaitent synchroniser le stock entre Dolibarr et Prestashop.&lt;br /&gt;
&lt;br /&gt;
Dolistock a été créé par [https://www.siladel.fr/ Siladel : Développeur Prestashop Albi] pour répondre à un besoin précis, une gestion fine des mouvements de stocks entre Dolibarr et PrestaShop..&lt;br /&gt;
&lt;br /&gt;
Sa particularité réside dans la sélection des produits a traiter et de prendre en compte une sélection de produit basé sur un type de référence (ID, REF, EAN13, UPC, ISBN).&lt;br /&gt;
&lt;br /&gt;
Concernant Dolibarr, les mouvements de stock générés par le module apparaissent de façon claire et précise.&lt;br /&gt;
&lt;br /&gt;
==Fonctionnement du module Dolistock :==&lt;br /&gt;
&lt;br /&gt;
===Synchronisation de Prestashop vers Dolibarr en temps réel===&lt;br /&gt;
&lt;br /&gt;
*Les articles expédiés décrémentent votre stock prestashop et celui de Dolibarr. &lt;br /&gt;
*Les retours d'articles incrémentent votre stock Prestashop et celui de Dolibarr. &lt;br /&gt;
*Les corrections de stocks effectuées sous prestashop '''ne sont pas synchonisées''' vers Dolibarr.&lt;br /&gt;
*La synchronisation des articles se fait de Prestashop vers Dolibarr pour l'entrepôt et les catégories sélectionnées uniquement. &lt;br /&gt;
*L'identifiant choisi doit correspondre sur Prestashop et Dolibarr. (Seuls, les articles ayant une similitude seront synchronisés).&lt;br /&gt;
&lt;br /&gt;
===Synchronisation de Dolibarr vers Prestashop===&lt;br /&gt;
&lt;br /&gt;
*La synchronisation des stocks de Dolibarr vers Prestashop se fait à l'aide d'une tâche CRON&lt;br /&gt;
*La synchronisation des stocks vers Prestashop se fait uniquement à partir de l'entrepôt et des catégories sélectionnées.&lt;br /&gt;
*La synchronisation peut se faire sur les produits en ventes ou pas (produits tagués en vente sur la fiche produit de Dolibarr).&lt;br /&gt;
*La synchronisation se fait uniquement sur les produits dont la quantité a été mise à jour.&lt;br /&gt;
*Les produits venant de Dolibarr sans stock ou avec stocks négatifs ou nuls seront enregistrés 0 stock sur Prestashop.&lt;br /&gt;
&lt;br /&gt;
==Installation==&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Conf01.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Entrez dans le back-office de Prestashop (la partie administration du site).&lt;br /&gt;
&lt;br /&gt;
Sur les onglets situés à gauche, cliquez sur &amp;quot;Modules&amp;quot; puis la page &amp;quot;modules et services&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Cliquez sur le bouton &amp;quot;Installer un module&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Faites glisser le fichier zip dans le cadre.&lt;br /&gt;
&lt;br /&gt;
Terminez l'installation en appuyant sur &amp;quot;Configurer&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Description des fonctions==&lt;br /&gt;
&lt;br /&gt;
[[Fichier:conf02.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''LOGS :'''&lt;br /&gt;
&lt;br /&gt;
Activer ou non les logs du module. Les fichiers logs se trouvent à la racine de PrestaShop dans le dossier app/logs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''CLE :'''&lt;br /&gt;
&lt;br /&gt;
Clé de l’Api générée à partir de Dolibarr. (cette clé se trouve sur la fiche utilisateur de Dolibarr).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''URL :'''&lt;br /&gt;
&lt;br /&gt;
Adresse du site Dolibarr , (Ex:  monsite.fr ou monsite.fr/htdocs)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Identifiant produit :'''&lt;br /&gt;
&lt;br /&gt;
Choisissez un identifiant similaire entre Dolibarr et PrestaShop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Entrepôt :'''&lt;br /&gt;
&lt;br /&gt;
Sélectionner l’entrepôt à synchroniser&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Stock négatif :'''&lt;br /&gt;
&lt;br /&gt;
Permet de recevoir des mouvements de stock PrestaShop vers Dolibarr alors que le produit se trouve&lt;br /&gt;
en rupture sur Dolibarr. (reprenez la même configuration de Dolibarr pour éviter de générer un&lt;br /&gt;
message d’alerte). cette fonction se trouve dans le module '''stock''' de Dolibarr (Règles d'exigence sur les stocks)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Catégorie :'''&lt;br /&gt;
&lt;br /&gt;
Sélectionnez 1 ou plusieurs catégories à l’aide de la touche CTRL.&lt;br /&gt;
&lt;br /&gt;
Seul les produits des catégories sélectionnées seront pris en compte lors de la synchronisation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Zone de mise à jour du stock manuellement :===&lt;br /&gt;
&lt;br /&gt;
Une fois la configuration du module terminée, vous pourrez lancer une mise à jour de vos stocks manuellement. &lt;br /&gt;
&lt;br /&gt;
A la fin de l’opération, le module vous indique le nombre de produits traités.&lt;br /&gt;
&lt;br /&gt;
Recommencez l’opération tant que le module vous retourne un nombre positif.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Produits en ventes :'''&lt;br /&gt;
&lt;br /&gt;
N’autorise que les produits tagués &amp;quot;en vente&amp;quot; sur Dolibarr et exclut le reste.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Tâche CRON'''&lt;br /&gt;
&lt;br /&gt;
Il s’agit de déclencher une tâche routinière d’administration système à une heure précise.&lt;br /&gt;
&lt;br /&gt;
Dolistock fournit un lien en bas de page permettant de synchroniser les stocks Dolibarr vers Prestashop. &lt;br /&gt;
Ce lien peut être copié dans votre gestionnaire de tâches planifiées Dolibarr sinon utiliser un service externe pour gérer vos tâches CRON.&lt;br /&gt;
&lt;br /&gt;
Également, le lien peut être généré avec le module par défaut '''Cron Jobs''' de PrestaShop.&lt;br /&gt;
&lt;br /&gt;
Dolibarr autorise la saisie de tâches CRON. Pour cela, activer le module « Travaux programmés » puis créer un « nouveau travail&lt;br /&gt;
planifié ». Ensuite, saisissez l’URL de la tâche CRON à la ligne « commande » et pour finir, configurez la fréquence d’exécution.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Contact ==&lt;br /&gt;
&lt;br /&gt;
Pour toutes questions sur les produits et services, veuillez nous contacter:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Siladel.png|link=https://www.siladel.fr|alt=développeur prestashop]]&lt;br /&gt;
&lt;br /&gt;
[https://www.siladel.fr/service/developpement-prestashop Développeur Prestashop]&lt;br /&gt;
&lt;br /&gt;
[https://www.dolistore.com/product.php?id=1365&amp;amp;title=dolistock&amp;amp;l=fr Module disponible sur Dolistore]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Eanprodoc&amp;diff=524</id>
		<title>Eanprodoc</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Eanprodoc&amp;diff=524"/>
				<updated>2025-08-30T10:18:55Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : /* Contact */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;EANPRODOC est un module Dolibarr permettant d'afficher les codes-barres de vos produits dans vos documents PDF.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Affichez les codes-barres de vos produits dans vos documents PDF (clients et fournisseurs).&lt;br /&gt;
* Insérez automatiquement vos codes produits dans vos factures, commandes et fiches d'expédition.&lt;br /&gt;
* Compatible avec tous les modèles PDF.&lt;br /&gt;
* Prend en charge tous les codes 1D (EAN8, EAN13, EAN128, GS1, ISBN, UPC).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Pour les version Dolibarr 6 et plus&lt;br /&gt;
*Depuis l'interface à la page Configuration &amp;gt; Modules/Applications Cliquez sur l'onglet Déployer/Installer un module externe.&lt;br /&gt;
&lt;br /&gt;
Après avoir terminé l'installation, rendez-vous sur la page de configuration du module pour activer les options de votre choix.&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
[[fichier:Config-eanprodoc.png|880px]]&lt;br /&gt;
&lt;br /&gt;
'''Affiche les codes-barres pour les factures.'''&lt;br /&gt;
Si un produit possède un code-barre, celui-ci sera affiché sur votre facture en PDF.&lt;br /&gt;
&lt;br /&gt;
'''Affiche les codes-barres pour les commandes.'''&lt;br /&gt;
Si un produit possède un code-barre, celui-ci sera visible sur votre bon de commande en PDF.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Affiche les codes-barres pour les fiches d'expéditions.'''&lt;br /&gt;
Si un produit possède un code-barre, celui-ci sera visible sur vos fiches d'expéditions en PDF.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Affiche les codes-barres pour les factures fournisseurs. '''&lt;br /&gt;
Si un produit possède un code-barre, celui-ci sera affiché sur votre facture fournisseur en PDF.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Affiche les codes-barres pour les commandes fournisseurs '''&lt;br /&gt;
Si un produit possède un code-barre, celui-ci sera visible sur votre bon de commande fournisseur en PDF.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Exclure le template commençant par : '''&lt;br /&gt;
permet d'indiquer le nom d'un modèle PDF dans lequel les codes-barres ne seront pas affichés.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Afficher la description sous le code-barres'''&lt;br /&gt;
Affiche le numero du code sous le code barre.&lt;br /&gt;
&lt;br /&gt;
[[fichier:Num_code_eanprodoc.png|800px]]&lt;br /&gt;
&lt;br /&gt;
'''Afficher la description sous le code-barres.'''&lt;br /&gt;
permet un retour à la ligne dans la description au niveau du code-barre.&lt;br /&gt;
&lt;br /&gt;
'''Largeur et Hauteur du code-barres, Largeur de la description'''&lt;br /&gt;
permet un positionnement précis du code-barres dans le document PDF.&lt;br /&gt;
&lt;br /&gt;
== Contact ==&lt;br /&gt;
&lt;br /&gt;
Pour toutes questions sur les produits et services, veuillez nous contacter:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Siladel.png|link=https://www.siladel.fr|alt=développeur web sur albi]]&lt;br /&gt;
&lt;br /&gt;
[https://www.siladel.fr/service/developpement-dolibarr Développeur Dolibarr]&lt;br /&gt;
&lt;br /&gt;
[https://www.dolistore.com/product.php?id=1049&amp;amp;title=eanprodoc&amp;amp;l=fr Module Eanprodoc disponible sur Dolistore]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Exportpresta&amp;diff=523</id>
		<title>Exportpresta</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Exportpresta&amp;diff=523"/>
				<updated>2025-08-30T10:15:45Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : /* Contact */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
ExportPresta est une solution (développée par [https://www.siladel.fr/ Siladel : Agence web Albi]) permettant d'aider les utilisateurs à exporter leurs produits Dolibarr vers PrestaShop.&lt;br /&gt;
&lt;br /&gt;
Ce module permet de générer des fichiers CSV compatibles avec PrestaShop.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ExportPresta comprend 3 méthodes d'exportations différentes permettant de répondre au mieux à chaque situation.&lt;br /&gt;
&lt;br /&gt;
Méthodes à partir du Core (Dolibarr 7+), méthode par référence, méthode par définition d'un SKU personnalisé avec définition d'attributs.&lt;br /&gt;
&lt;br /&gt;
*Exporte les produits simples ou déclinés.&lt;br /&gt;
*Exporte les images, attributs, catégories, codeb-arres[EAN13, UPS, ISBN], stock, prix de vos produits et déclinaisons&lt;br /&gt;
*Exporte selon vos catégories, entrepôts, stocks.&lt;br /&gt;
*Ajustement du prix final.&lt;br /&gt;
*Exporte vos impacts sur le prix et le poids&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Décompressez le fichier dans le dossier &amp;quot;htdocs/custom&amp;quot; ou à la racine htdocs/ (suivant votre configuration)&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
'''Mode à partir du core de Dolibarr v7+'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Rien à saisir dans ce mode. Les attributs sont générés avec le module par défaut &amp;quot;Variante Produit&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Avant de générer vos fichiers CSV, il ne faudra pas oublier d'activer l'option &amp;quot;Rendre accessible les images des produits pour PrestaShop&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Cela générera les liens dans vos fichiers pour que PrestaShop puisse ensuite trouver les images.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:prest_conf01.png]]&lt;br /&gt;
&lt;br /&gt;
'''Mode à partir d'une référence produit.'''&lt;br /&gt;
&lt;br /&gt;
Ce mode est pour vous si les références de vos déclinaisons possèdent un caractère de séparation et que vous n'utilisez pas le module par défaut&lt;br /&gt;
&amp;quot;Variante de produits &amp;quot; ou que votre version de Dolibarr est inférieure à la version 7.&lt;br /&gt;
&lt;br /&gt;
Avant de générer vos fichiers CSV, il ne faudra pas oublier d'activer l'option &amp;quot;Rendre accessible les images des produits pour PrestaShop&amp;quot;&lt;br /&gt;
&lt;br /&gt;
cela générera les liens dans vos fichiers pour que PrestaShop puisse ensuite trouver les images.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:prest_conf02.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Mode à partir d'un SKU personnalisé'''&lt;br /&gt;
&lt;br /&gt;
Vous pouvez activer ce mode, dans le cas où vos produits sont créés avec un SKU (une référence de famille produit) à l'aide des &amp;quot;champs personnalisés&amp;quot; du module &amp;quot;Produits&amp;quot; et que vous possédez des attributs supplémentaires comme par exemple(taille, couleur, modèle) sur tous vos produits.&lt;br /&gt;
&lt;br /&gt;
Avant de générer vos fichiers CSV, il ne faudra pas oublier d'activer l'option &amp;quot;Rendre accessible les images des produits pour PrestaShop&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Cela générera les liens dans vos fichiers pour que PrestaShop puisse ensuite trouver les images. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:Conf03.png]]&lt;br /&gt;
&lt;br /&gt;
== Utilisation ==&lt;br /&gt;
&lt;br /&gt;
Pour afficher la page ci-dessous vous devez vous rendre sur l'onglet '''Outils''' puis '''Export Prestashop'''&lt;br /&gt;
&lt;br /&gt;
Cette page permet de générer un fichier CSV de vos produits sans les déclinaisons.&lt;br /&gt;
&lt;br /&gt;
===1. Paramètres de sélection pour Dolibarr ===&lt;br /&gt;
Cette zone sert à sélectionner les produits dont vous avez besoin.&lt;br /&gt;
&lt;br /&gt;
*Tag/catégorie pour les produits liés à une catégorie.&lt;br /&gt;
*L'entrepôt.(A condition d'avoir du stock dans l'entrepôt).&lt;br /&gt;
*Uniquement les produits en vente (tagués en Vente sur la fiche produit).&lt;br /&gt;
*Uniquement les produits en stock.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===2. Paramètres d'importation pour PrestaShop ===&lt;br /&gt;
Cette zone sert à ajouter des propriétés utiles dans votre fichier CSV. Elles seront ensuite prises en compte sous PrestaShop.&lt;br /&gt;
&lt;br /&gt;
*Taux de marge ; Pour effectuer un ajustement du prix final.&lt;br /&gt;
*Id boutique ; Identifiant de la boutique PrestaShop (laissez vide, si vous ne gérez qu’une seule boutique).&lt;br /&gt;
*Qty en fonction du stock ; Pour utiliser la quantité définie par l'entrepôt.&lt;br /&gt;
*Gestion des stocks Avancés ; Active la gestion des stocks avancés sur tous les produits.&lt;br /&gt;
*Uniquement en ligne ; Produit tagué &amp;quot;exclusivement en ligne&amp;quot; pour le client final.&lt;br /&gt;
*Effacer les images existantes ; Activez cette fonction pour remplacer les images des produits par celle du fichier.&lt;br /&gt;
*Identifiant TVA ; généralement sur 1. (TVA 20%)&lt;br /&gt;
*En vente ; Produit en vente sous PrestaShop&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
[[Fichier:Screenshot_exportpresta.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Attention''' !&lt;br /&gt;
&lt;br /&gt;
'''Ce module n'est pas parfait et parfois, l'exportation peut donner un résultat incomplet.'''&lt;br /&gt;
&lt;br /&gt;
'''Dans ce cas, les corrections doivent être réalisées manuellement à l'aide du logiciel LibreOffice ou Microsoft Excel.'''&lt;br /&gt;
&lt;br /&gt;
== Contact ==&lt;br /&gt;
&lt;br /&gt;
Pour toutes questions sur les produits et services, veuillez nous contacter:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Siladel.png|link=https://www.siladel.fr|alt=développeur prestashop sur albi]]&lt;br /&gt;
&lt;br /&gt;
[https://www.siladel.fr/service/developpement-prestashop Développeur Prestashop]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Addinventory&amp;diff=522</id>
		<title>Addinventory</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Addinventory&amp;diff=522"/>
				<updated>2025-08-30T10:14:06Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : /* Contact */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
ADDINVENTORY est un module Dolibarr permettant de modifier rapidement votre stock à partir d'un liste de produit, lots, déclinaison.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Correction en masse du stock à partir d'une liste (lot et déclinaison compris).&lt;br /&gt;
*Création en masse de lots.&lt;br /&gt;
*Fait gagner du temps lors des mouvements de stocks.&lt;br /&gt;
*Un tableau vous permet d'avoir un aperçu des référents en un coup d'œil.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Pour les version Dolibarr 6 et plus&lt;br /&gt;
*Depuis l'interface à la page Configuration &amp;gt; Modules/Applications Cliquez sur l'onglet Déployer/Installer un module externe.&lt;br /&gt;
&lt;br /&gt;
Une fois l'installation terminé, les pages &amp;quot;Inventaire &amp;amp; correction&amp;quot; et &amp;quot;Stocks référents&amp;quot; seront disponibles dans l'onglet &amp;quot;Produits | services&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
[[Fichier:Conf addinventory2.png|880px]]&lt;br /&gt;
&lt;br /&gt;
'''Activer les quantités décimales :'''&lt;br /&gt;
&lt;br /&gt;
Activez cette fonction pour une gestion du stock basé sur les décimaux.&lt;br /&gt;
&lt;br /&gt;
'''Correction de stock par quantité Delta :'''&lt;br /&gt;
&lt;br /&gt;
Permet de renseigner la quantité totale d'un produit mais la quantité à ajouter ou à supprimer.&lt;br /&gt;
Vous avez alors le choix entre saisir manuellement la quantité à ajouter ou à supprimer en incluant le signe moins - ou utiliser les flèches pour ajuster la quantité.&lt;br /&gt;
&lt;br /&gt;
'''Correction de stock par substitution :'''&lt;br /&gt;
&lt;br /&gt;
Il s'agit simplement de renseigner la quantité totale d'un produit.&lt;br /&gt;
&lt;br /&gt;
'''Proposez aux utilisateurs de choisir le mode (Delta ou par substitution) dans la page &amp;quot;Inventaire &amp;amp; correction&amp;quot; '''&lt;br /&gt;
&lt;br /&gt;
Permet de switcher entre les deux modes aux choix dans la page &amp;quot;Inventaire &amp;amp; correction&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''Rendre possible de modifier le stock sur les produits parents contenant des variants'''&lt;br /&gt;
&lt;br /&gt;
Par défaut Dolibarr ne permet pas de saisir du stock sur les produits parents variants.&lt;br /&gt;
A utiliser dans de cas bien précis, par corriger des erreurs par exemple.&lt;br /&gt;
&lt;br /&gt;
'''Afficher les services '''&lt;br /&gt;
&lt;br /&gt;
Affiche dans la liste tous les produits de type service.&lt;br /&gt;
&lt;br /&gt;
'''Activer la saisie du prix d'achat.'''&lt;br /&gt;
&lt;br /&gt;
Permet de saisir le prix d'achat unitaire de l'ensemble des produits nouvellement ajoutés.&lt;br /&gt;
&lt;br /&gt;
'''Permettre la création de nouveaux lots.'''&lt;br /&gt;
&lt;br /&gt;
Pour chaque produit de type lot, la fonction complète sur une ligne les champs indispensables pour saisir de nouveaux lots. voir l'exemple ci-dessous&lt;br /&gt;
(n° de lot, entrepôt, DLC, DMD/DLUO, prix achat, stock)&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Conf addinventory list.png|900px]]&lt;br /&gt;
&lt;br /&gt;
== Fonctionnement correction du stock ==&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Doc_addinventory.png|880px]]&lt;br /&gt;
&lt;br /&gt;
Pour modifier le stock d'un seul produit, renseignez simplement la quantité totale du produit ou la quantité à ajouter (suivant la méthode définie dans la page configuration) dans le champ de saisie.&lt;br /&gt;
&lt;br /&gt;
'''En mode quantité Delta :'''&lt;br /&gt;
Ce que vous saisissez dans cette entrée est un delta de la quantité, ce qui signifie que ce n'est pas la valeur de stock finale souhaitée, mais la quantité que vous ajoutez ou supprimez. Vous pouvez soit taper la quantité à ajouter ou à supprimer (avec un signe moins), soit utiliser les flèches haut et bas pour ajuster la quantité.&lt;br /&gt;
&lt;br /&gt;
'''En mode par substitution :'''&lt;br /&gt;
Renseignez simplement la quantité totale du produit disponible en stock.&lt;br /&gt;
&lt;br /&gt;
Pour valider le nouveau stock, cliquez simplement sur le bouton &amp;quot;Enregistrer&amp;quot; situé en bas de page.&lt;br /&gt;
&lt;br /&gt;
'''Information !'''&lt;br /&gt;
&lt;br /&gt;
Lors de la recherche avec un entrepôt défini, les produits apparaissent seulement si un stock existe. sinon, vous devrez effectuer une recherche sans définir l’entrepôt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Addinventory_screen04.jpg|880px]]&lt;br /&gt;
&lt;br /&gt;
Pour chaque correction effectuée sur le stock, Dolibarr enregistre un mouvement de stock avec le delta de la quantité positif ou négatif quelle que soit la méthode utilisée (delta ou substitution).&lt;br /&gt;
&lt;br /&gt;
== Page Stocks référents ==&lt;br /&gt;
[[Fichier:Addinventory screen03.jpg|880px]]&lt;br /&gt;
&lt;br /&gt;
'''Stock physique'''&lt;br /&gt;
&lt;br /&gt;
Le stock physique représente la quantité que vous avez réellement physiquement dans votre entrepôt.&lt;br /&gt;
&lt;br /&gt;
'''Stock virtuel'''&lt;br /&gt;
&lt;br /&gt;
Le stock virtuel est la quantité de produit en stock après que les opération affectant les stock sont terminées (réceptions de commandes fournisseurs, expéditions de commandes clients,...)&lt;br /&gt;
&lt;br /&gt;
'''Qty commandes clients'''&lt;br /&gt;
&lt;br /&gt;
Quantité de produit en commandes client ouvertes&lt;br /&gt;
&lt;br /&gt;
'''Qty factures clients'''&lt;br /&gt;
&lt;br /&gt;
Quantité de produit en factures client ouvertes&lt;br /&gt;
&lt;br /&gt;
== Contact ==&lt;br /&gt;
&lt;br /&gt;
Pour toutes questions sur les produits et services, veuillez nous contacter:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Siladel.png|link=https://www.siladel.fr|alt=développeur web sur albi]]&lt;br /&gt;
&lt;br /&gt;
[https://www.siladel.fr/service/developpement-dolibarr Développeur Dolibarr]&lt;br /&gt;
&lt;br /&gt;
[https://www.dolistore.com/product.php?id=1190&amp;amp;title=addinventory&amp;amp;l=fr Module addinventory disponible sur Dolistore]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Addinventory&amp;diff=521</id>
		<title>Addinventory</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Addinventory&amp;diff=521"/>
				<updated>2025-08-30T10:13:27Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : /* Contact */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
ADDINVENTORY est un module Dolibarr permettant de modifier rapidement votre stock à partir d'un liste de produit, lots, déclinaison.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Correction en masse du stock à partir d'une liste (lot et déclinaison compris).&lt;br /&gt;
*Création en masse de lots.&lt;br /&gt;
*Fait gagner du temps lors des mouvements de stocks.&lt;br /&gt;
*Un tableau vous permet d'avoir un aperçu des référents en un coup d'œil.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Pour les version Dolibarr 6 et plus&lt;br /&gt;
*Depuis l'interface à la page Configuration &amp;gt; Modules/Applications Cliquez sur l'onglet Déployer/Installer un module externe.&lt;br /&gt;
&lt;br /&gt;
Une fois l'installation terminé, les pages &amp;quot;Inventaire &amp;amp; correction&amp;quot; et &amp;quot;Stocks référents&amp;quot; seront disponibles dans l'onglet &amp;quot;Produits | services&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
[[Fichier:Conf addinventory2.png|880px]]&lt;br /&gt;
&lt;br /&gt;
'''Activer les quantités décimales :'''&lt;br /&gt;
&lt;br /&gt;
Activez cette fonction pour une gestion du stock basé sur les décimaux.&lt;br /&gt;
&lt;br /&gt;
'''Correction de stock par quantité Delta :'''&lt;br /&gt;
&lt;br /&gt;
Permet de renseigner la quantité totale d'un produit mais la quantité à ajouter ou à supprimer.&lt;br /&gt;
Vous avez alors le choix entre saisir manuellement la quantité à ajouter ou à supprimer en incluant le signe moins - ou utiliser les flèches pour ajuster la quantité.&lt;br /&gt;
&lt;br /&gt;
'''Correction de stock par substitution :'''&lt;br /&gt;
&lt;br /&gt;
Il s'agit simplement de renseigner la quantité totale d'un produit.&lt;br /&gt;
&lt;br /&gt;
'''Proposez aux utilisateurs de choisir le mode (Delta ou par substitution) dans la page &amp;quot;Inventaire &amp;amp; correction&amp;quot; '''&lt;br /&gt;
&lt;br /&gt;
Permet de switcher entre les deux modes aux choix dans la page &amp;quot;Inventaire &amp;amp; correction&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''Rendre possible de modifier le stock sur les produits parents contenant des variants'''&lt;br /&gt;
&lt;br /&gt;
Par défaut Dolibarr ne permet pas de saisir du stock sur les produits parents variants.&lt;br /&gt;
A utiliser dans de cas bien précis, par corriger des erreurs par exemple.&lt;br /&gt;
&lt;br /&gt;
'''Afficher les services '''&lt;br /&gt;
&lt;br /&gt;
Affiche dans la liste tous les produits de type service.&lt;br /&gt;
&lt;br /&gt;
'''Activer la saisie du prix d'achat.'''&lt;br /&gt;
&lt;br /&gt;
Permet de saisir le prix d'achat unitaire de l'ensemble des produits nouvellement ajoutés.&lt;br /&gt;
&lt;br /&gt;
'''Permettre la création de nouveaux lots.'''&lt;br /&gt;
&lt;br /&gt;
Pour chaque produit de type lot, la fonction complète sur une ligne les champs indispensables pour saisir de nouveaux lots. voir l'exemple ci-dessous&lt;br /&gt;
(n° de lot, entrepôt, DLC, DMD/DLUO, prix achat, stock)&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Conf addinventory list.png|900px]]&lt;br /&gt;
&lt;br /&gt;
== Fonctionnement correction du stock ==&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Doc_addinventory.png|880px]]&lt;br /&gt;
&lt;br /&gt;
Pour modifier le stock d'un seul produit, renseignez simplement la quantité totale du produit ou la quantité à ajouter (suivant la méthode définie dans la page configuration) dans le champ de saisie.&lt;br /&gt;
&lt;br /&gt;
'''En mode quantité Delta :'''&lt;br /&gt;
Ce que vous saisissez dans cette entrée est un delta de la quantité, ce qui signifie que ce n'est pas la valeur de stock finale souhaitée, mais la quantité que vous ajoutez ou supprimez. Vous pouvez soit taper la quantité à ajouter ou à supprimer (avec un signe moins), soit utiliser les flèches haut et bas pour ajuster la quantité.&lt;br /&gt;
&lt;br /&gt;
'''En mode par substitution :'''&lt;br /&gt;
Renseignez simplement la quantité totale du produit disponible en stock.&lt;br /&gt;
&lt;br /&gt;
Pour valider le nouveau stock, cliquez simplement sur le bouton &amp;quot;Enregistrer&amp;quot; situé en bas de page.&lt;br /&gt;
&lt;br /&gt;
'''Information !'''&lt;br /&gt;
&lt;br /&gt;
Lors de la recherche avec un entrepôt défini, les produits apparaissent seulement si un stock existe. sinon, vous devrez effectuer une recherche sans définir l’entrepôt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Addinventory_screen04.jpg|880px]]&lt;br /&gt;
&lt;br /&gt;
Pour chaque correction effectuée sur le stock, Dolibarr enregistre un mouvement de stock avec le delta de la quantité positif ou négatif quelle que soit la méthode utilisée (delta ou substitution).&lt;br /&gt;
&lt;br /&gt;
== Page Stocks référents ==&lt;br /&gt;
[[Fichier:Addinventory screen03.jpg|880px]]&lt;br /&gt;
&lt;br /&gt;
'''Stock physique'''&lt;br /&gt;
&lt;br /&gt;
Le stock physique représente la quantité que vous avez réellement physiquement dans votre entrepôt.&lt;br /&gt;
&lt;br /&gt;
'''Stock virtuel'''&lt;br /&gt;
&lt;br /&gt;
Le stock virtuel est la quantité de produit en stock après que les opération affectant les stock sont terminées (réceptions de commandes fournisseurs, expéditions de commandes clients,...)&lt;br /&gt;
&lt;br /&gt;
'''Qty commandes clients'''&lt;br /&gt;
&lt;br /&gt;
Quantité de produit en commandes client ouvertes&lt;br /&gt;
&lt;br /&gt;
'''Qty factures clients'''&lt;br /&gt;
&lt;br /&gt;
Quantité de produit en factures client ouvertes&lt;br /&gt;
&lt;br /&gt;
== Contact ==&lt;br /&gt;
&lt;br /&gt;
Pour toutes questions sur les produits et services, veuillez nous contacter:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Siladel.png|link=https://www.siladel.fr|alt=développeur web sur albi]]&lt;br /&gt;
&lt;br /&gt;
[https://www.siladel.fr/service/developpement-dolibarr Développement Dolibarr sur Albi]&lt;br /&gt;
&lt;br /&gt;
[https://www.dolistore.com/product.php?id=1190&amp;amp;title=addinventory&amp;amp;l=fr Module addinventory disponible sur Dolistore]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Addremise&amp;diff=520</id>
		<title>Addremise</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Addremise&amp;diff=520"/>
				<updated>2025-08-30T10:11:27Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : /* Contact */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Module permettant de saisir une remise globale en pourcentage lors de la création de devis, commandes et factures.&lt;br /&gt;
&lt;br /&gt;
ADDRemise inclut la gestion des permissions utilisateurs, la configuration des libellés ainsi que la prise en charge de la TVA.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Déployez un module externe en utilisant l'assistant d'installation disponible dans Configuration &amp;gt; Modules &amp;amp; Applications.&lt;br /&gt;
&lt;br /&gt;
Vous pouvez également décompressez le fichier dans le dossier &amp;quot;htdocs/custom&amp;quot; ou à la racine htdocs/&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
Une fois le module installé, vous devez l'activer dans l'application Dolibarr via la session &amp;quot;Modules/Applications&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Conf.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Les paramètres de configurations ==&lt;br /&gt;
&lt;br /&gt;
[[Fichier:addremise_setting1.7.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Paramétrage d'activation ===&lt;br /&gt;
Choisissez d'activer ou non Addremise pour les devis, commandes, factures.&lt;br /&gt;
&lt;br /&gt;
=== Libellés des remises globales par défaut ===&lt;br /&gt;
Permet d'ajouter une description à votre remise après le pourcentage.&lt;br /&gt;
par exemple par défaut 10% &amp;quot;de remise client&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Paramètres additionnels : ===&lt;br /&gt;
*'''Affiche la ligne remise globale dans la liste des produits :'''&lt;br /&gt;
**Activez cette option si vous voulez faire apparaitre la remise globale en même temps que la liste des produits&lt;br /&gt;
&lt;br /&gt;
*'''Ne pas comptabiliser les produits offerts en tant que remise.'''&lt;br /&gt;
**Par défaut sur Dolibarr, les remises 100% appliquées sur les produits donc gratuit sont comptabilisées en tant que remise.&lt;br /&gt;
**Vous pouvez désactiver cette option pour ne pas comptabiliser les produits gratuit ou offert en tant que remise.&lt;br /&gt;
&lt;br /&gt;
*'''Afficher les produits offerts sur la même ligne que les produits vendus.'''&lt;br /&gt;
**Il s’agit de regrouper les produits de même référence offert ou pas sur une ligne.&lt;br /&gt;
&lt;br /&gt;
*'''Ne pas afficher le taux des remises dans les totaux.'''&lt;br /&gt;
**désactive le pourcentage de remise dans les totaux. &amp;quot;Total remise&amp;quot; ou &amp;quot;Total remise (5%)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*'''Ne pas afficher la colonne TVA dans le PDF.'''&lt;br /&gt;
**Permet simplement de ne pas afiicher la colonne TVA dans le tableau des produits.&lt;br /&gt;
**N'activer cette option si vous avez plusieurs taux de TVA.&lt;br /&gt;
&lt;br /&gt;
== Permissions et droits d’accès ==&lt;br /&gt;
Par défaut les permissions sont activées pour l'administrateur. &lt;br /&gt;
Pour gérer les permissions en rapport avec le module, allez dans le menu &amp;quot;Utilisateurs &amp;amp; Groupes&amp;quot;, sélectionnez un utilisateur ou un groupe puis l'onglet &amp;quot;permissions utilisateur&amp;quot; ou &amp;quot;permissions groupe&amp;quot; dans le cas d'un groupe.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:permit.jpg]]&lt;br /&gt;
&lt;br /&gt;
== Activer modèle facture PDF avec remise ==&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Screen pdf.jpg|800px]]&lt;br /&gt;
&lt;br /&gt;
Pour activer le modèle crabe en PDF avec les remises dans les totaux, vous devez vous rendre dans la configuration du module '''Factures et avoirs''' qui se trouve dans la session Modules/Applications.&lt;br /&gt;
&lt;br /&gt;
* La remise dans les totaux s'affiche également lorsque vous appliquez une remise standard (remise sur ligne de produit).&lt;br /&gt;
* Vous pouvez additionner les remises sur ligne produit et une remise globale.&lt;br /&gt;
&lt;br /&gt;
== Utilisation ==&lt;br /&gt;
Après installation et activation des remises pour les factures.&lt;br /&gt;
&lt;br /&gt;
Un bouton remise doit apparaître pendant la saisie de votre facture.&lt;br /&gt;
Vous décidez d'ajouter une remise, vous appuyez sur le bouton remise, une fenêtre s'affiche, dans la partie 1, vous saisissez votre pourcentage. Par exemple, le chiffre 10 pour 10%, dans la partie 2, vous saisissez votre texte, dans la partie 3, votre TVA.&lt;br /&gt;
&lt;br /&gt;
Normalement, sauf cas exceptionnel, vous ne devez pas modifier la TVA de votre remise, la remise doit avoir le même taux de TVA que les produits.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Comportement de la remise lorsque vous ajoutez un produit après avoir intégré une remise globale'''&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;&lt;br /&gt;
La remise globale appliquée sur un document se mettra à jour automatiquement après modification.&lt;br /&gt;
Une seule remise globale peut être appliquée par document.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Contact ==&lt;br /&gt;
&lt;br /&gt;
Pour toutes questions sur les produits et services, veuillez nous contacter:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Siladel.png|link=https://www.siladel.fr|alt=développeur Saas sur albi]]&lt;br /&gt;
&lt;br /&gt;
[https://www.siladel.fr/service/developpement-dolibarr Développeur de module Dolibarr]&lt;br /&gt;
&lt;br /&gt;
[https://www.dolistore.com/product.php?id=1660&amp;amp;title=addremise&amp;amp;l=fr Module remise disponible sur Dolistore]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Viewmap&amp;diff=519</id>
		<title>Viewmap</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Viewmap&amp;diff=519"/>
				<updated>2025-08-30T10:10:01Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : /* Contact */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Le module Viewmap permet de géolocaliser vos différents tiers, tels que les prospects, les clients, les fournisseurs, les contacts et les adhérents, sur une carte Google Maps. En effet, lors de la création d'un nouveau tiers, ce module effectue automatiquement la géolocalisation de son adresse et vous offre la capacité d'afficher l'ensemble de vos tiers sur une carte unique.&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Depuis l'interface à la page Configuration &amp;gt; Modules/Applications Cliquez sur l'onglet Déployer/Installer un module externe.&lt;br /&gt;
&lt;br /&gt;
Après avoir terminé l'installation, rendez-vous sur la page de configuration pour saisir votre clé Google Map.&lt;br /&gt;
&lt;br /&gt;
La carte sera accessible depuis l'onglet &amp;quot;outils&amp;quot; et également sur les fiches de vos tiers.&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
Une fois l'installation du module terminée dans l'application Dolibarr, vous devez activer le module qui se trouve dans la session Modules/Applications&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Viewmap index.jpg| 900px ]]&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Viewmap screen config.jpg|900px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Test du géocodage pendant le processus de création'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Vous pouvez tester de géolocaliser une adresse postale pendant la saisie d'un nouveau tiers avec l'option &amp;quot;Test du géocodage pendant le processus de création&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Clé Google Map'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;&lt;br /&gt;
Pour afficher une carte Google Maps sur votre Dolibarr, il est nécessaire de spécifier une clé d'API. Nous allons voir dans ce tutoriel comment l'obtenir et l'utiliser dans votre module Viwmap.&lt;br /&gt;
&lt;br /&gt;
Pour être en mesure d'obtenir une clé d'API, il est nécessaire de disposer au préalable d'un compte Gmail. Si ce n'est pas votre cas, vous devez en créer un au préalable.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Zoom de la fiche client et de la carte '''&lt;br /&gt;
&lt;br /&gt;
Vous pouvez modifier le zoom des cartes. &lt;br /&gt;
*1 = Le monde entier&lt;br /&gt;
*6 = La France entière &lt;br /&gt;
*11 = un département&lt;br /&gt;
*16 = un quartier&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Clusterisation des marqueurs sur la carte principale'''&lt;br /&gt;
&lt;br /&gt;
Cette fonction permet de regrouper les markers en zone.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Géocodage en masse de vos contacts'''&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Geocodage_setting.png]]&lt;br /&gt;
&lt;br /&gt;
Pour chaque clic sur le bouton &amp;quot;géocoder&amp;quot; vous effectuez un géocodage sur 100 adresses. &lt;br /&gt;
&lt;br /&gt;
Appuyez sur autant de fois que nécessaire pour géocoder l'ensemble de vos contacts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;&lt;br /&gt;
L'utilisation de l'API Google Geocoding est limitée par un quota de 2.500 requêtes de géolocalisation par jour.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''' Effacer les données du géocodage'''&lt;br /&gt;
&lt;br /&gt;
Cette fonction supprimer les coordonnées GPS de tous vos société/contacts.&lt;br /&gt;
&lt;br /&gt;
''' Définir ses propres marqueurs '''&lt;br /&gt;
&lt;br /&gt;
Le module propose de remplacer les marqueurs par défaut suivant le type de tier.&lt;br /&gt;
&lt;br /&gt;
il est recommandé d'utiliser des images de 48px maximum au format PNG, GIF, JPG&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Viewmap marqueurs.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Obtenir une clé d'API Google Map:==&lt;br /&gt;
&lt;br /&gt;
Pour obtenir cette clé, vous devez vous rendre sur [https://console.developers.google.com/flows/enableapi?apiid=maps_backend&amp;amp;keyType=CLIENT_SIDE&amp;amp;reusekey=true&amp;amp;hl=fr&amp;amp;pli=1 console.developers.google.com]&lt;br /&gt;
&lt;br /&gt;
===1. Création d'un nouveau projet===&lt;br /&gt;
&lt;br /&gt;
S'il s'agit de votre première connexion sur la console, vous allez automatiquement créer un nouveau projet qui sera nommé &amp;quot;My Projet&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Il suffit de cocher 2 cases :&lt;br /&gt;
&lt;br /&gt;
*indiquez si vous souhaitez recevoir ou non l'actualité Google APIs &lt;br /&gt;
*acceptez les conditions d'utilisation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===2. Création de la clé===&lt;br /&gt;
&lt;br /&gt;
*Vous devez nommer la clé ou laisser le nom par défaut &amp;quot;Clé API 1&amp;quot;&lt;br /&gt;
*Pour sécuriser votre clé, appliquez une restriction en choisissant &amp;quot;Adresse IP&amp;quot; et entrez l'adresse IP de votre serveur Dolibarr. Ainsi, seule cette adresse sera autorisée à utiliser la clé.&lt;br /&gt;
*Assurez-vous d'associer à votre clé les API suivantes : &amp;quot;Maps JavaScript API&amp;quot; et &amp;quot;Geocoding API&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Depuis le 11 juin 2018, il est obligatoire d’activer un compte de facturation afin de pouvoir utiliser les services Google Maps.&lt;br /&gt;
Toutefois, Google fournit généralement un crédit gratuit mensuel, ce qui signifie que pour une utilisation modérée, il n'y a souvent pas de frais réels à payer.&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;&lt;br /&gt;
Important : Viewmap fait appel à l'API de géocodage uniquement une seule fois lors de la géolocalisation de l'adresse.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Poursuivez en cliquant sur &amp;quot;Créer&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===3. Votre clé a été créée===&lt;br /&gt;
Une nouvelle fenêtre s'affiche avec votre clé d'API. Copiez-la pour l'intégrer dans votre configuration Viewmap.&lt;br /&gt;
&lt;br /&gt;
== Utilisation ==&lt;br /&gt;
&lt;br /&gt;
=== Carte sur la fiche client ===&lt;br /&gt;
&lt;br /&gt;
Géocoder une adresse postale sur la fiche d'un tiers :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Viewmaptier.jpg | 700px]]&lt;br /&gt;
&lt;br /&gt;
=== Option d'affichage ===&lt;br /&gt;
&lt;br /&gt;
Contrôle des données lorsque vous utilisez l'API Viewmap.&lt;br /&gt;
&lt;br /&gt;
Pour le tier en cours, vous pouvez choisir de masquer certaine information comme l’e-mail, téléphone, Url ou ne rien afficher.&lt;br /&gt;
&lt;br /&gt;
(cette fonctionnalité est prise en compte uniquement avec l'API Viewmap)&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Viewmap option api.jpg | 900px]]&lt;br /&gt;
&lt;br /&gt;
=== Carte d'ensemble ===&lt;br /&gt;
&lt;br /&gt;
Dans Outils, une carte est disponible pour visualiser l'ensemble des tiers.&lt;br /&gt;
&lt;br /&gt;
Vous pouvez filtrer vos données par type de tier, pays, département, catégorie ou par commerciaux&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Viewmap map2.jpg | 900px]]&lt;br /&gt;
&lt;br /&gt;
== Contact ==&lt;br /&gt;
&lt;br /&gt;
Pour toutes questions sur les produits et services, veuillez nous contacter:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Siladel.png|link=https://www.siladel.fr|alt=développeur web sur albi]]&lt;br /&gt;
&lt;br /&gt;
[https://www.siladel.fr/service/developpement-dolibarr Développeur Dolibarr]&lt;br /&gt;
&lt;br /&gt;
[https://www.dolistore.com/product.php?id=1398&amp;amp;title=viewmap&amp;amp;l=fr Module disponible sur Dolistore]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Viewmap&amp;diff=518</id>
		<title>Viewmap</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Viewmap&amp;diff=518"/>
				<updated>2025-08-30T10:09:49Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : /* Contact */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Le module Viewmap permet de géolocaliser vos différents tiers, tels que les prospects, les clients, les fournisseurs, les contacts et les adhérents, sur une carte Google Maps. En effet, lors de la création d'un nouveau tiers, ce module effectue automatiquement la géolocalisation de son adresse et vous offre la capacité d'afficher l'ensemble de vos tiers sur une carte unique.&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Depuis l'interface à la page Configuration &amp;gt; Modules/Applications Cliquez sur l'onglet Déployer/Installer un module externe.&lt;br /&gt;
&lt;br /&gt;
Après avoir terminé l'installation, rendez-vous sur la page de configuration pour saisir votre clé Google Map.&lt;br /&gt;
&lt;br /&gt;
La carte sera accessible depuis l'onglet &amp;quot;outils&amp;quot; et également sur les fiches de vos tiers.&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
Une fois l'installation du module terminée dans l'application Dolibarr, vous devez activer le module qui se trouve dans la session Modules/Applications&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Viewmap index.jpg| 900px ]]&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Viewmap screen config.jpg|900px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Test du géocodage pendant le processus de création'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Vous pouvez tester de géolocaliser une adresse postale pendant la saisie d'un nouveau tiers avec l'option &amp;quot;Test du géocodage pendant le processus de création&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Clé Google Map'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;&lt;br /&gt;
Pour afficher une carte Google Maps sur votre Dolibarr, il est nécessaire de spécifier une clé d'API. Nous allons voir dans ce tutoriel comment l'obtenir et l'utiliser dans votre module Viwmap.&lt;br /&gt;
&lt;br /&gt;
Pour être en mesure d'obtenir une clé d'API, il est nécessaire de disposer au préalable d'un compte Gmail. Si ce n'est pas votre cas, vous devez en créer un au préalable.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Zoom de la fiche client et de la carte '''&lt;br /&gt;
&lt;br /&gt;
Vous pouvez modifier le zoom des cartes. &lt;br /&gt;
*1 = Le monde entier&lt;br /&gt;
*6 = La France entière &lt;br /&gt;
*11 = un département&lt;br /&gt;
*16 = un quartier&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Clusterisation des marqueurs sur la carte principale'''&lt;br /&gt;
&lt;br /&gt;
Cette fonction permet de regrouper les markers en zone.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Géocodage en masse de vos contacts'''&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Geocodage_setting.png]]&lt;br /&gt;
&lt;br /&gt;
Pour chaque clic sur le bouton &amp;quot;géocoder&amp;quot; vous effectuez un géocodage sur 100 adresses. &lt;br /&gt;
&lt;br /&gt;
Appuyez sur autant de fois que nécessaire pour géocoder l'ensemble de vos contacts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;&lt;br /&gt;
L'utilisation de l'API Google Geocoding est limitée par un quota de 2.500 requêtes de géolocalisation par jour.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''' Effacer les données du géocodage'''&lt;br /&gt;
&lt;br /&gt;
Cette fonction supprimer les coordonnées GPS de tous vos société/contacts.&lt;br /&gt;
&lt;br /&gt;
''' Définir ses propres marqueurs '''&lt;br /&gt;
&lt;br /&gt;
Le module propose de remplacer les marqueurs par défaut suivant le type de tier.&lt;br /&gt;
&lt;br /&gt;
il est recommandé d'utiliser des images de 48px maximum au format PNG, GIF, JPG&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Viewmap marqueurs.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Obtenir une clé d'API Google Map:==&lt;br /&gt;
&lt;br /&gt;
Pour obtenir cette clé, vous devez vous rendre sur [https://console.developers.google.com/flows/enableapi?apiid=maps_backend&amp;amp;keyType=CLIENT_SIDE&amp;amp;reusekey=true&amp;amp;hl=fr&amp;amp;pli=1 console.developers.google.com]&lt;br /&gt;
&lt;br /&gt;
===1. Création d'un nouveau projet===&lt;br /&gt;
&lt;br /&gt;
S'il s'agit de votre première connexion sur la console, vous allez automatiquement créer un nouveau projet qui sera nommé &amp;quot;My Projet&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Il suffit de cocher 2 cases :&lt;br /&gt;
&lt;br /&gt;
*indiquez si vous souhaitez recevoir ou non l'actualité Google APIs &lt;br /&gt;
*acceptez les conditions d'utilisation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===2. Création de la clé===&lt;br /&gt;
&lt;br /&gt;
*Vous devez nommer la clé ou laisser le nom par défaut &amp;quot;Clé API 1&amp;quot;&lt;br /&gt;
*Pour sécuriser votre clé, appliquez une restriction en choisissant &amp;quot;Adresse IP&amp;quot; et entrez l'adresse IP de votre serveur Dolibarr. Ainsi, seule cette adresse sera autorisée à utiliser la clé.&lt;br /&gt;
*Assurez-vous d'associer à votre clé les API suivantes : &amp;quot;Maps JavaScript API&amp;quot; et &amp;quot;Geocoding API&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Depuis le 11 juin 2018, il est obligatoire d’activer un compte de facturation afin de pouvoir utiliser les services Google Maps.&lt;br /&gt;
Toutefois, Google fournit généralement un crédit gratuit mensuel, ce qui signifie que pour une utilisation modérée, il n'y a souvent pas de frais réels à payer.&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;&lt;br /&gt;
Important : Viewmap fait appel à l'API de géocodage uniquement une seule fois lors de la géolocalisation de l'adresse.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Poursuivez en cliquant sur &amp;quot;Créer&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===3. Votre clé a été créée===&lt;br /&gt;
Une nouvelle fenêtre s'affiche avec votre clé d'API. Copiez-la pour l'intégrer dans votre configuration Viewmap.&lt;br /&gt;
&lt;br /&gt;
== Utilisation ==&lt;br /&gt;
&lt;br /&gt;
=== Carte sur la fiche client ===&lt;br /&gt;
&lt;br /&gt;
Géocoder une adresse postale sur la fiche d'un tiers :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Viewmaptier.jpg | 700px]]&lt;br /&gt;
&lt;br /&gt;
=== Option d'affichage ===&lt;br /&gt;
&lt;br /&gt;
Contrôle des données lorsque vous utilisez l'API Viewmap.&lt;br /&gt;
&lt;br /&gt;
Pour le tier en cours, vous pouvez choisir de masquer certaine information comme l’e-mail, téléphone, Url ou ne rien afficher.&lt;br /&gt;
&lt;br /&gt;
(cette fonctionnalité est prise en compte uniquement avec l'API Viewmap)&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Viewmap option api.jpg | 900px]]&lt;br /&gt;
&lt;br /&gt;
=== Carte d'ensemble ===&lt;br /&gt;
&lt;br /&gt;
Dans Outils, une carte est disponible pour visualiser l'ensemble des tiers.&lt;br /&gt;
&lt;br /&gt;
Vous pouvez filtrer vos données par type de tier, pays, département, catégorie ou par commerciaux&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Viewmap map2.jpg | 900px]]&lt;br /&gt;
&lt;br /&gt;
== Contact ==&lt;br /&gt;
&lt;br /&gt;
Pour toutes questions sur les produits et services, veuillez nous contacter:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Siladel.png|link=https://www.siladel.fr|alt=développeur web sur albi]]&lt;br /&gt;
&lt;br /&gt;
[https://www.siladel.fr/service/developpement-dolibarr Développeur Dolibarr]&lt;br /&gt;
&lt;br /&gt;
[https://www.dolistore.com/product.php?id=1398&amp;amp;title=viewmap&amp;amp;l=fr produit disponible sur Dolistore]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Viewmap&amp;diff=517</id>
		<title>Viewmap</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Viewmap&amp;diff=517"/>
				<updated>2025-08-30T10:08:17Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : /* Contact */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Le module Viewmap permet de géolocaliser vos différents tiers, tels que les prospects, les clients, les fournisseurs, les contacts et les adhérents, sur une carte Google Maps. En effet, lors de la création d'un nouveau tiers, ce module effectue automatiquement la géolocalisation de son adresse et vous offre la capacité d'afficher l'ensemble de vos tiers sur une carte unique.&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Depuis l'interface à la page Configuration &amp;gt; Modules/Applications Cliquez sur l'onglet Déployer/Installer un module externe.&lt;br /&gt;
&lt;br /&gt;
Après avoir terminé l'installation, rendez-vous sur la page de configuration pour saisir votre clé Google Map.&lt;br /&gt;
&lt;br /&gt;
La carte sera accessible depuis l'onglet &amp;quot;outils&amp;quot; et également sur les fiches de vos tiers.&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
Une fois l'installation du module terminée dans l'application Dolibarr, vous devez activer le module qui se trouve dans la session Modules/Applications&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Viewmap index.jpg| 900px ]]&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Viewmap screen config.jpg|900px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Test du géocodage pendant le processus de création'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Vous pouvez tester de géolocaliser une adresse postale pendant la saisie d'un nouveau tiers avec l'option &amp;quot;Test du géocodage pendant le processus de création&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Clé Google Map'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;&lt;br /&gt;
Pour afficher une carte Google Maps sur votre Dolibarr, il est nécessaire de spécifier une clé d'API. Nous allons voir dans ce tutoriel comment l'obtenir et l'utiliser dans votre module Viwmap.&lt;br /&gt;
&lt;br /&gt;
Pour être en mesure d'obtenir une clé d'API, il est nécessaire de disposer au préalable d'un compte Gmail. Si ce n'est pas votre cas, vous devez en créer un au préalable.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Zoom de la fiche client et de la carte '''&lt;br /&gt;
&lt;br /&gt;
Vous pouvez modifier le zoom des cartes. &lt;br /&gt;
*1 = Le monde entier&lt;br /&gt;
*6 = La France entière &lt;br /&gt;
*11 = un département&lt;br /&gt;
*16 = un quartier&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Clusterisation des marqueurs sur la carte principale'''&lt;br /&gt;
&lt;br /&gt;
Cette fonction permet de regrouper les markers en zone.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Géocodage en masse de vos contacts'''&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Geocodage_setting.png]]&lt;br /&gt;
&lt;br /&gt;
Pour chaque clic sur le bouton &amp;quot;géocoder&amp;quot; vous effectuez un géocodage sur 100 adresses. &lt;br /&gt;
&lt;br /&gt;
Appuyez sur autant de fois que nécessaire pour géocoder l'ensemble de vos contacts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;&lt;br /&gt;
L'utilisation de l'API Google Geocoding est limitée par un quota de 2.500 requêtes de géolocalisation par jour.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''' Effacer les données du géocodage'''&lt;br /&gt;
&lt;br /&gt;
Cette fonction supprimer les coordonnées GPS de tous vos société/contacts.&lt;br /&gt;
&lt;br /&gt;
''' Définir ses propres marqueurs '''&lt;br /&gt;
&lt;br /&gt;
Le module propose de remplacer les marqueurs par défaut suivant le type de tier.&lt;br /&gt;
&lt;br /&gt;
il est recommandé d'utiliser des images de 48px maximum au format PNG, GIF, JPG&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Viewmap marqueurs.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Obtenir une clé d'API Google Map:==&lt;br /&gt;
&lt;br /&gt;
Pour obtenir cette clé, vous devez vous rendre sur [https://console.developers.google.com/flows/enableapi?apiid=maps_backend&amp;amp;keyType=CLIENT_SIDE&amp;amp;reusekey=true&amp;amp;hl=fr&amp;amp;pli=1 console.developers.google.com]&lt;br /&gt;
&lt;br /&gt;
===1. Création d'un nouveau projet===&lt;br /&gt;
&lt;br /&gt;
S'il s'agit de votre première connexion sur la console, vous allez automatiquement créer un nouveau projet qui sera nommé &amp;quot;My Projet&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Il suffit de cocher 2 cases :&lt;br /&gt;
&lt;br /&gt;
*indiquez si vous souhaitez recevoir ou non l'actualité Google APIs &lt;br /&gt;
*acceptez les conditions d'utilisation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===2. Création de la clé===&lt;br /&gt;
&lt;br /&gt;
*Vous devez nommer la clé ou laisser le nom par défaut &amp;quot;Clé API 1&amp;quot;&lt;br /&gt;
*Pour sécuriser votre clé, appliquez une restriction en choisissant &amp;quot;Adresse IP&amp;quot; et entrez l'adresse IP de votre serveur Dolibarr. Ainsi, seule cette adresse sera autorisée à utiliser la clé.&lt;br /&gt;
*Assurez-vous d'associer à votre clé les API suivantes : &amp;quot;Maps JavaScript API&amp;quot; et &amp;quot;Geocoding API&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Depuis le 11 juin 2018, il est obligatoire d’activer un compte de facturation afin de pouvoir utiliser les services Google Maps.&lt;br /&gt;
Toutefois, Google fournit généralement un crédit gratuit mensuel, ce qui signifie que pour une utilisation modérée, il n'y a souvent pas de frais réels à payer.&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;&lt;br /&gt;
Important : Viewmap fait appel à l'API de géocodage uniquement une seule fois lors de la géolocalisation de l'adresse.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Poursuivez en cliquant sur &amp;quot;Créer&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===3. Votre clé a été créée===&lt;br /&gt;
Une nouvelle fenêtre s'affiche avec votre clé d'API. Copiez-la pour l'intégrer dans votre configuration Viewmap.&lt;br /&gt;
&lt;br /&gt;
== Utilisation ==&lt;br /&gt;
&lt;br /&gt;
=== Carte sur la fiche client ===&lt;br /&gt;
&lt;br /&gt;
Géocoder une adresse postale sur la fiche d'un tiers :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Viewmaptier.jpg | 700px]]&lt;br /&gt;
&lt;br /&gt;
=== Option d'affichage ===&lt;br /&gt;
&lt;br /&gt;
Contrôle des données lorsque vous utilisez l'API Viewmap.&lt;br /&gt;
&lt;br /&gt;
Pour le tier en cours, vous pouvez choisir de masquer certaine information comme l’e-mail, téléphone, Url ou ne rien afficher.&lt;br /&gt;
&lt;br /&gt;
(cette fonctionnalité est prise en compte uniquement avec l'API Viewmap)&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Viewmap option api.jpg | 900px]]&lt;br /&gt;
&lt;br /&gt;
=== Carte d'ensemble ===&lt;br /&gt;
&lt;br /&gt;
Dans Outils, une carte est disponible pour visualiser l'ensemble des tiers.&lt;br /&gt;
&lt;br /&gt;
Vous pouvez filtrer vos données par type de tier, pays, département, catégorie ou par commerciaux&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Viewmap map2.jpg | 900px]]&lt;br /&gt;
&lt;br /&gt;
== Contact ==&lt;br /&gt;
&lt;br /&gt;
Pour toutes questions sur les produits et services, veuillez nous contacter:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Siladel.png|link=https://www.siladel.fr|alt=développeur web sur albi]]&lt;br /&gt;
&lt;br /&gt;
[https://www.siladel.fr/service/developpement-dolibarr Développeur Dolibarr]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Addinventory&amp;diff=516</id>
		<title>Addinventory</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Addinventory&amp;diff=516"/>
				<updated>2025-08-30T09:48:15Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : /* Contact */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
ADDINVENTORY est un module Dolibarr permettant de modifier rapidement votre stock à partir d'un liste de produit, lots, déclinaison.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Correction en masse du stock à partir d'une liste (lot et déclinaison compris).&lt;br /&gt;
*Création en masse de lots.&lt;br /&gt;
*Fait gagner du temps lors des mouvements de stocks.&lt;br /&gt;
*Un tableau vous permet d'avoir un aperçu des référents en un coup d'œil.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Pour les version Dolibarr 6 et plus&lt;br /&gt;
*Depuis l'interface à la page Configuration &amp;gt; Modules/Applications Cliquez sur l'onglet Déployer/Installer un module externe.&lt;br /&gt;
&lt;br /&gt;
Une fois l'installation terminé, les pages &amp;quot;Inventaire &amp;amp; correction&amp;quot; et &amp;quot;Stocks référents&amp;quot; seront disponibles dans l'onglet &amp;quot;Produits | services&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
[[Fichier:Conf addinventory2.png|880px]]&lt;br /&gt;
&lt;br /&gt;
'''Activer les quantités décimales :'''&lt;br /&gt;
&lt;br /&gt;
Activez cette fonction pour une gestion du stock basé sur les décimaux.&lt;br /&gt;
&lt;br /&gt;
'''Correction de stock par quantité Delta :'''&lt;br /&gt;
&lt;br /&gt;
Permet de renseigner la quantité totale d'un produit mais la quantité à ajouter ou à supprimer.&lt;br /&gt;
Vous avez alors le choix entre saisir manuellement la quantité à ajouter ou à supprimer en incluant le signe moins - ou utiliser les flèches pour ajuster la quantité.&lt;br /&gt;
&lt;br /&gt;
'''Correction de stock par substitution :'''&lt;br /&gt;
&lt;br /&gt;
Il s'agit simplement de renseigner la quantité totale d'un produit.&lt;br /&gt;
&lt;br /&gt;
'''Proposez aux utilisateurs de choisir le mode (Delta ou par substitution) dans la page &amp;quot;Inventaire &amp;amp; correction&amp;quot; '''&lt;br /&gt;
&lt;br /&gt;
Permet de switcher entre les deux modes aux choix dans la page &amp;quot;Inventaire &amp;amp; correction&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''Rendre possible de modifier le stock sur les produits parents contenant des variants'''&lt;br /&gt;
&lt;br /&gt;
Par défaut Dolibarr ne permet pas de saisir du stock sur les produits parents variants.&lt;br /&gt;
A utiliser dans de cas bien précis, par corriger des erreurs par exemple.&lt;br /&gt;
&lt;br /&gt;
'''Afficher les services '''&lt;br /&gt;
&lt;br /&gt;
Affiche dans la liste tous les produits de type service.&lt;br /&gt;
&lt;br /&gt;
'''Activer la saisie du prix d'achat.'''&lt;br /&gt;
&lt;br /&gt;
Permet de saisir le prix d'achat unitaire de l'ensemble des produits nouvellement ajoutés.&lt;br /&gt;
&lt;br /&gt;
'''Permettre la création de nouveaux lots.'''&lt;br /&gt;
&lt;br /&gt;
Pour chaque produit de type lot, la fonction complète sur une ligne les champs indispensables pour saisir de nouveaux lots. voir l'exemple ci-dessous&lt;br /&gt;
(n° de lot, entrepôt, DLC, DMD/DLUO, prix achat, stock)&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Conf addinventory list.png|900px]]&lt;br /&gt;
&lt;br /&gt;
== Fonctionnement correction du stock ==&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Doc_addinventory.png|880px]]&lt;br /&gt;
&lt;br /&gt;
Pour modifier le stock d'un seul produit, renseignez simplement la quantité totale du produit ou la quantité à ajouter (suivant la méthode définie dans la page configuration) dans le champ de saisie.&lt;br /&gt;
&lt;br /&gt;
'''En mode quantité Delta :'''&lt;br /&gt;
Ce que vous saisissez dans cette entrée est un delta de la quantité, ce qui signifie que ce n'est pas la valeur de stock finale souhaitée, mais la quantité que vous ajoutez ou supprimez. Vous pouvez soit taper la quantité à ajouter ou à supprimer (avec un signe moins), soit utiliser les flèches haut et bas pour ajuster la quantité.&lt;br /&gt;
&lt;br /&gt;
'''En mode par substitution :'''&lt;br /&gt;
Renseignez simplement la quantité totale du produit disponible en stock.&lt;br /&gt;
&lt;br /&gt;
Pour valider le nouveau stock, cliquez simplement sur le bouton &amp;quot;Enregistrer&amp;quot; situé en bas de page.&lt;br /&gt;
&lt;br /&gt;
'''Information !'''&lt;br /&gt;
&lt;br /&gt;
Lors de la recherche avec un entrepôt défini, les produits apparaissent seulement si un stock existe. sinon, vous devrez effectuer une recherche sans définir l’entrepôt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Addinventory_screen04.jpg|880px]]&lt;br /&gt;
&lt;br /&gt;
Pour chaque correction effectuée sur le stock, Dolibarr enregistre un mouvement de stock avec le delta de la quantité positif ou négatif quelle que soit la méthode utilisée (delta ou substitution).&lt;br /&gt;
&lt;br /&gt;
== Page Stocks référents ==&lt;br /&gt;
[[Fichier:Addinventory screen03.jpg|880px]]&lt;br /&gt;
&lt;br /&gt;
'''Stock physique'''&lt;br /&gt;
&lt;br /&gt;
Le stock physique représente la quantité que vous avez réellement physiquement dans votre entrepôt.&lt;br /&gt;
&lt;br /&gt;
'''Stock virtuel'''&lt;br /&gt;
&lt;br /&gt;
Le stock virtuel est la quantité de produit en stock après que les opération affectant les stock sont terminées (réceptions de commandes fournisseurs, expéditions de commandes clients,...)&lt;br /&gt;
&lt;br /&gt;
'''Qty commandes clients'''&lt;br /&gt;
&lt;br /&gt;
Quantité de produit en commandes client ouvertes&lt;br /&gt;
&lt;br /&gt;
'''Qty factures clients'''&lt;br /&gt;
&lt;br /&gt;
Quantité de produit en factures client ouvertes&lt;br /&gt;
&lt;br /&gt;
== Contact ==&lt;br /&gt;
&lt;br /&gt;
Pour toutes questions sur les produits et services, veuillez nous contacter:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Siladel.png|link=https://www.siladel.fr|alt=développeur web sur albi]]&lt;br /&gt;
&lt;br /&gt;
[https://www.siladel.fr/service/developpement-dolibarr Développement personnalisé Dolibarr]&lt;br /&gt;
&lt;br /&gt;
[https://www.dolistore.com/index.php?controller=search&amp;amp;orderby=position&amp;amp;orderway=desc&amp;amp;tag=&amp;amp;website=marketplace&amp;amp;search_query=siladel Vente en ligne de nos modules]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Addinventory&amp;diff=515</id>
		<title>Addinventory</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Addinventory&amp;diff=515"/>
				<updated>2025-08-30T09:47:46Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : /* Contact */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
ADDINVENTORY est un module Dolibarr permettant de modifier rapidement votre stock à partir d'un liste de produit, lots, déclinaison.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Correction en masse du stock à partir d'une liste (lot et déclinaison compris).&lt;br /&gt;
*Création en masse de lots.&lt;br /&gt;
*Fait gagner du temps lors des mouvements de stocks.&lt;br /&gt;
*Un tableau vous permet d'avoir un aperçu des référents en un coup d'œil.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Pour les version Dolibarr 6 et plus&lt;br /&gt;
*Depuis l'interface à la page Configuration &amp;gt; Modules/Applications Cliquez sur l'onglet Déployer/Installer un module externe.&lt;br /&gt;
&lt;br /&gt;
Une fois l'installation terminé, les pages &amp;quot;Inventaire &amp;amp; correction&amp;quot; et &amp;quot;Stocks référents&amp;quot; seront disponibles dans l'onglet &amp;quot;Produits | services&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
[[Fichier:Conf addinventory2.png|880px]]&lt;br /&gt;
&lt;br /&gt;
'''Activer les quantités décimales :'''&lt;br /&gt;
&lt;br /&gt;
Activez cette fonction pour une gestion du stock basé sur les décimaux.&lt;br /&gt;
&lt;br /&gt;
'''Correction de stock par quantité Delta :'''&lt;br /&gt;
&lt;br /&gt;
Permet de renseigner la quantité totale d'un produit mais la quantité à ajouter ou à supprimer.&lt;br /&gt;
Vous avez alors le choix entre saisir manuellement la quantité à ajouter ou à supprimer en incluant le signe moins - ou utiliser les flèches pour ajuster la quantité.&lt;br /&gt;
&lt;br /&gt;
'''Correction de stock par substitution :'''&lt;br /&gt;
&lt;br /&gt;
Il s'agit simplement de renseigner la quantité totale d'un produit.&lt;br /&gt;
&lt;br /&gt;
'''Proposez aux utilisateurs de choisir le mode (Delta ou par substitution) dans la page &amp;quot;Inventaire &amp;amp; correction&amp;quot; '''&lt;br /&gt;
&lt;br /&gt;
Permet de switcher entre les deux modes aux choix dans la page &amp;quot;Inventaire &amp;amp; correction&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''Rendre possible de modifier le stock sur les produits parents contenant des variants'''&lt;br /&gt;
&lt;br /&gt;
Par défaut Dolibarr ne permet pas de saisir du stock sur les produits parents variants.&lt;br /&gt;
A utiliser dans de cas bien précis, par corriger des erreurs par exemple.&lt;br /&gt;
&lt;br /&gt;
'''Afficher les services '''&lt;br /&gt;
&lt;br /&gt;
Affiche dans la liste tous les produits de type service.&lt;br /&gt;
&lt;br /&gt;
'''Activer la saisie du prix d'achat.'''&lt;br /&gt;
&lt;br /&gt;
Permet de saisir le prix d'achat unitaire de l'ensemble des produits nouvellement ajoutés.&lt;br /&gt;
&lt;br /&gt;
'''Permettre la création de nouveaux lots.'''&lt;br /&gt;
&lt;br /&gt;
Pour chaque produit de type lot, la fonction complète sur une ligne les champs indispensables pour saisir de nouveaux lots. voir l'exemple ci-dessous&lt;br /&gt;
(n° de lot, entrepôt, DLC, DMD/DLUO, prix achat, stock)&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Conf addinventory list.png|900px]]&lt;br /&gt;
&lt;br /&gt;
== Fonctionnement correction du stock ==&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Doc_addinventory.png|880px]]&lt;br /&gt;
&lt;br /&gt;
Pour modifier le stock d'un seul produit, renseignez simplement la quantité totale du produit ou la quantité à ajouter (suivant la méthode définie dans la page configuration) dans le champ de saisie.&lt;br /&gt;
&lt;br /&gt;
'''En mode quantité Delta :'''&lt;br /&gt;
Ce que vous saisissez dans cette entrée est un delta de la quantité, ce qui signifie que ce n'est pas la valeur de stock finale souhaitée, mais la quantité que vous ajoutez ou supprimez. Vous pouvez soit taper la quantité à ajouter ou à supprimer (avec un signe moins), soit utiliser les flèches haut et bas pour ajuster la quantité.&lt;br /&gt;
&lt;br /&gt;
'''En mode par substitution :'''&lt;br /&gt;
Renseignez simplement la quantité totale du produit disponible en stock.&lt;br /&gt;
&lt;br /&gt;
Pour valider le nouveau stock, cliquez simplement sur le bouton &amp;quot;Enregistrer&amp;quot; situé en bas de page.&lt;br /&gt;
&lt;br /&gt;
'''Information !'''&lt;br /&gt;
&lt;br /&gt;
Lors de la recherche avec un entrepôt défini, les produits apparaissent seulement si un stock existe. sinon, vous devrez effectuer une recherche sans définir l’entrepôt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Addinventory_screen04.jpg|880px]]&lt;br /&gt;
&lt;br /&gt;
Pour chaque correction effectuée sur le stock, Dolibarr enregistre un mouvement de stock avec le delta de la quantité positif ou négatif quelle que soit la méthode utilisée (delta ou substitution).&lt;br /&gt;
&lt;br /&gt;
== Page Stocks référents ==&lt;br /&gt;
[[Fichier:Addinventory screen03.jpg|880px]]&lt;br /&gt;
&lt;br /&gt;
'''Stock physique'''&lt;br /&gt;
&lt;br /&gt;
Le stock physique représente la quantité que vous avez réellement physiquement dans votre entrepôt.&lt;br /&gt;
&lt;br /&gt;
'''Stock virtuel'''&lt;br /&gt;
&lt;br /&gt;
Le stock virtuel est la quantité de produit en stock après que les opération affectant les stock sont terminées (réceptions de commandes fournisseurs, expéditions de commandes clients,...)&lt;br /&gt;
&lt;br /&gt;
'''Qty commandes clients'''&lt;br /&gt;
&lt;br /&gt;
Quantité de produit en commandes client ouvertes&lt;br /&gt;
&lt;br /&gt;
'''Qty factures clients'''&lt;br /&gt;
&lt;br /&gt;
Quantité de produit en factures client ouvertes&lt;br /&gt;
&lt;br /&gt;
== Contact ==&lt;br /&gt;
&lt;br /&gt;
Pour toutes questions sur les produits et services, veuillez nous contacter:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Siladel.png|link=https://www.siladel.fr|alt=développeur web sur albi|rel=dofollow]]&lt;br /&gt;
&lt;br /&gt;
[https://www.siladel.fr/service/developpement-dolibarr Développement personnalisé Dolibarr]&lt;br /&gt;
&lt;br /&gt;
[https://www.dolistore.com/index.php?controller=search&amp;amp;orderby=position&amp;amp;orderway=desc&amp;amp;tag=&amp;amp;website=marketplace&amp;amp;search_query=siladel Vente en ligne de nos modules]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Addinventory&amp;diff=514</id>
		<title>Addinventory</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Addinventory&amp;diff=514"/>
				<updated>2025-08-30T09:44:32Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : /* Contact */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
ADDINVENTORY est un module Dolibarr permettant de modifier rapidement votre stock à partir d'un liste de produit, lots, déclinaison.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Correction en masse du stock à partir d'une liste (lot et déclinaison compris).&lt;br /&gt;
*Création en masse de lots.&lt;br /&gt;
*Fait gagner du temps lors des mouvements de stocks.&lt;br /&gt;
*Un tableau vous permet d'avoir un aperçu des référents en un coup d'œil.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Pour les version Dolibarr 6 et plus&lt;br /&gt;
*Depuis l'interface à la page Configuration &amp;gt; Modules/Applications Cliquez sur l'onglet Déployer/Installer un module externe.&lt;br /&gt;
&lt;br /&gt;
Une fois l'installation terminé, les pages &amp;quot;Inventaire &amp;amp; correction&amp;quot; et &amp;quot;Stocks référents&amp;quot; seront disponibles dans l'onglet &amp;quot;Produits | services&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
[[Fichier:Conf addinventory2.png|880px]]&lt;br /&gt;
&lt;br /&gt;
'''Activer les quantités décimales :'''&lt;br /&gt;
&lt;br /&gt;
Activez cette fonction pour une gestion du stock basé sur les décimaux.&lt;br /&gt;
&lt;br /&gt;
'''Correction de stock par quantité Delta :'''&lt;br /&gt;
&lt;br /&gt;
Permet de renseigner la quantité totale d'un produit mais la quantité à ajouter ou à supprimer.&lt;br /&gt;
Vous avez alors le choix entre saisir manuellement la quantité à ajouter ou à supprimer en incluant le signe moins - ou utiliser les flèches pour ajuster la quantité.&lt;br /&gt;
&lt;br /&gt;
'''Correction de stock par substitution :'''&lt;br /&gt;
&lt;br /&gt;
Il s'agit simplement de renseigner la quantité totale d'un produit.&lt;br /&gt;
&lt;br /&gt;
'''Proposez aux utilisateurs de choisir le mode (Delta ou par substitution) dans la page &amp;quot;Inventaire &amp;amp; correction&amp;quot; '''&lt;br /&gt;
&lt;br /&gt;
Permet de switcher entre les deux modes aux choix dans la page &amp;quot;Inventaire &amp;amp; correction&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''Rendre possible de modifier le stock sur les produits parents contenant des variants'''&lt;br /&gt;
&lt;br /&gt;
Par défaut Dolibarr ne permet pas de saisir du stock sur les produits parents variants.&lt;br /&gt;
A utiliser dans de cas bien précis, par corriger des erreurs par exemple.&lt;br /&gt;
&lt;br /&gt;
'''Afficher les services '''&lt;br /&gt;
&lt;br /&gt;
Affiche dans la liste tous les produits de type service.&lt;br /&gt;
&lt;br /&gt;
'''Activer la saisie du prix d'achat.'''&lt;br /&gt;
&lt;br /&gt;
Permet de saisir le prix d'achat unitaire de l'ensemble des produits nouvellement ajoutés.&lt;br /&gt;
&lt;br /&gt;
'''Permettre la création de nouveaux lots.'''&lt;br /&gt;
&lt;br /&gt;
Pour chaque produit de type lot, la fonction complète sur une ligne les champs indispensables pour saisir de nouveaux lots. voir l'exemple ci-dessous&lt;br /&gt;
(n° de lot, entrepôt, DLC, DMD/DLUO, prix achat, stock)&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Conf addinventory list.png|900px]]&lt;br /&gt;
&lt;br /&gt;
== Fonctionnement correction du stock ==&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Doc_addinventory.png|880px]]&lt;br /&gt;
&lt;br /&gt;
Pour modifier le stock d'un seul produit, renseignez simplement la quantité totale du produit ou la quantité à ajouter (suivant la méthode définie dans la page configuration) dans le champ de saisie.&lt;br /&gt;
&lt;br /&gt;
'''En mode quantité Delta :'''&lt;br /&gt;
Ce que vous saisissez dans cette entrée est un delta de la quantité, ce qui signifie que ce n'est pas la valeur de stock finale souhaitée, mais la quantité que vous ajoutez ou supprimez. Vous pouvez soit taper la quantité à ajouter ou à supprimer (avec un signe moins), soit utiliser les flèches haut et bas pour ajuster la quantité.&lt;br /&gt;
&lt;br /&gt;
'''En mode par substitution :'''&lt;br /&gt;
Renseignez simplement la quantité totale du produit disponible en stock.&lt;br /&gt;
&lt;br /&gt;
Pour valider le nouveau stock, cliquez simplement sur le bouton &amp;quot;Enregistrer&amp;quot; situé en bas de page.&lt;br /&gt;
&lt;br /&gt;
'''Information !'''&lt;br /&gt;
&lt;br /&gt;
Lors de la recherche avec un entrepôt défini, les produits apparaissent seulement si un stock existe. sinon, vous devrez effectuer une recherche sans définir l’entrepôt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Addinventory_screen04.jpg|880px]]&lt;br /&gt;
&lt;br /&gt;
Pour chaque correction effectuée sur le stock, Dolibarr enregistre un mouvement de stock avec le delta de la quantité positif ou négatif quelle que soit la méthode utilisée (delta ou substitution).&lt;br /&gt;
&lt;br /&gt;
== Page Stocks référents ==&lt;br /&gt;
[[Fichier:Addinventory screen03.jpg|880px]]&lt;br /&gt;
&lt;br /&gt;
'''Stock physique'''&lt;br /&gt;
&lt;br /&gt;
Le stock physique représente la quantité que vous avez réellement physiquement dans votre entrepôt.&lt;br /&gt;
&lt;br /&gt;
'''Stock virtuel'''&lt;br /&gt;
&lt;br /&gt;
Le stock virtuel est la quantité de produit en stock après que les opération affectant les stock sont terminées (réceptions de commandes fournisseurs, expéditions de commandes clients,...)&lt;br /&gt;
&lt;br /&gt;
'''Qty commandes clients'''&lt;br /&gt;
&lt;br /&gt;
Quantité de produit en commandes client ouvertes&lt;br /&gt;
&lt;br /&gt;
'''Qty factures clients'''&lt;br /&gt;
&lt;br /&gt;
Quantité de produit en factures client ouvertes&lt;br /&gt;
&lt;br /&gt;
== Contact ==&lt;br /&gt;
&lt;br /&gt;
Pour toutes questions sur les produits et services, veuillez nous contacter:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Siladel.png|link=https://www.siladel.fr|alt=développeur web sur albi]]&lt;br /&gt;
&lt;br /&gt;
[https://www.siladel.fr/service/developpement-dolibarr Développement personnalisé Dolibarr]&lt;br /&gt;
&lt;br /&gt;
[https://www.dolistore.com/index.php?controller=search&amp;amp;orderby=position&amp;amp;orderway=desc&amp;amp;tag=&amp;amp;website=marketplace&amp;amp;search_query=siladel Vente en ligne de nos modules]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Addinventory&amp;diff=513</id>
		<title>Addinventory</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Addinventory&amp;diff=513"/>
				<updated>2025-08-30T09:43:47Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : /* Contact */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
ADDINVENTORY est un module Dolibarr permettant de modifier rapidement votre stock à partir d'un liste de produit, lots, déclinaison.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Correction en masse du stock à partir d'une liste (lot et déclinaison compris).&lt;br /&gt;
*Création en masse de lots.&lt;br /&gt;
*Fait gagner du temps lors des mouvements de stocks.&lt;br /&gt;
*Un tableau vous permet d'avoir un aperçu des référents en un coup d'œil.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Pour les version Dolibarr 6 et plus&lt;br /&gt;
*Depuis l'interface à la page Configuration &amp;gt; Modules/Applications Cliquez sur l'onglet Déployer/Installer un module externe.&lt;br /&gt;
&lt;br /&gt;
Une fois l'installation terminé, les pages &amp;quot;Inventaire &amp;amp; correction&amp;quot; et &amp;quot;Stocks référents&amp;quot; seront disponibles dans l'onglet &amp;quot;Produits | services&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
[[Fichier:Conf addinventory2.png|880px]]&lt;br /&gt;
&lt;br /&gt;
'''Activer les quantités décimales :'''&lt;br /&gt;
&lt;br /&gt;
Activez cette fonction pour une gestion du stock basé sur les décimaux.&lt;br /&gt;
&lt;br /&gt;
'''Correction de stock par quantité Delta :'''&lt;br /&gt;
&lt;br /&gt;
Permet de renseigner la quantité totale d'un produit mais la quantité à ajouter ou à supprimer.&lt;br /&gt;
Vous avez alors le choix entre saisir manuellement la quantité à ajouter ou à supprimer en incluant le signe moins - ou utiliser les flèches pour ajuster la quantité.&lt;br /&gt;
&lt;br /&gt;
'''Correction de stock par substitution :'''&lt;br /&gt;
&lt;br /&gt;
Il s'agit simplement de renseigner la quantité totale d'un produit.&lt;br /&gt;
&lt;br /&gt;
'''Proposez aux utilisateurs de choisir le mode (Delta ou par substitution) dans la page &amp;quot;Inventaire &amp;amp; correction&amp;quot; '''&lt;br /&gt;
&lt;br /&gt;
Permet de switcher entre les deux modes aux choix dans la page &amp;quot;Inventaire &amp;amp; correction&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''Rendre possible de modifier le stock sur les produits parents contenant des variants'''&lt;br /&gt;
&lt;br /&gt;
Par défaut Dolibarr ne permet pas de saisir du stock sur les produits parents variants.&lt;br /&gt;
A utiliser dans de cas bien précis, par corriger des erreurs par exemple.&lt;br /&gt;
&lt;br /&gt;
'''Afficher les services '''&lt;br /&gt;
&lt;br /&gt;
Affiche dans la liste tous les produits de type service.&lt;br /&gt;
&lt;br /&gt;
'''Activer la saisie du prix d'achat.'''&lt;br /&gt;
&lt;br /&gt;
Permet de saisir le prix d'achat unitaire de l'ensemble des produits nouvellement ajoutés.&lt;br /&gt;
&lt;br /&gt;
'''Permettre la création de nouveaux lots.'''&lt;br /&gt;
&lt;br /&gt;
Pour chaque produit de type lot, la fonction complète sur une ligne les champs indispensables pour saisir de nouveaux lots. voir l'exemple ci-dessous&lt;br /&gt;
(n° de lot, entrepôt, DLC, DMD/DLUO, prix achat, stock)&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Conf addinventory list.png|900px]]&lt;br /&gt;
&lt;br /&gt;
== Fonctionnement correction du stock ==&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Doc_addinventory.png|880px]]&lt;br /&gt;
&lt;br /&gt;
Pour modifier le stock d'un seul produit, renseignez simplement la quantité totale du produit ou la quantité à ajouter (suivant la méthode définie dans la page configuration) dans le champ de saisie.&lt;br /&gt;
&lt;br /&gt;
'''En mode quantité Delta :'''&lt;br /&gt;
Ce que vous saisissez dans cette entrée est un delta de la quantité, ce qui signifie que ce n'est pas la valeur de stock finale souhaitée, mais la quantité que vous ajoutez ou supprimez. Vous pouvez soit taper la quantité à ajouter ou à supprimer (avec un signe moins), soit utiliser les flèches haut et bas pour ajuster la quantité.&lt;br /&gt;
&lt;br /&gt;
'''En mode par substitution :'''&lt;br /&gt;
Renseignez simplement la quantité totale du produit disponible en stock.&lt;br /&gt;
&lt;br /&gt;
Pour valider le nouveau stock, cliquez simplement sur le bouton &amp;quot;Enregistrer&amp;quot; situé en bas de page.&lt;br /&gt;
&lt;br /&gt;
'''Information !'''&lt;br /&gt;
&lt;br /&gt;
Lors de la recherche avec un entrepôt défini, les produits apparaissent seulement si un stock existe. sinon, vous devrez effectuer une recherche sans définir l’entrepôt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Addinventory_screen04.jpg|880px]]&lt;br /&gt;
&lt;br /&gt;
Pour chaque correction effectuée sur le stock, Dolibarr enregistre un mouvement de stock avec le delta de la quantité positif ou négatif quelle que soit la méthode utilisée (delta ou substitution).&lt;br /&gt;
&lt;br /&gt;
== Page Stocks référents ==&lt;br /&gt;
[[Fichier:Addinventory screen03.jpg|880px]]&lt;br /&gt;
&lt;br /&gt;
'''Stock physique'''&lt;br /&gt;
&lt;br /&gt;
Le stock physique représente la quantité que vous avez réellement physiquement dans votre entrepôt.&lt;br /&gt;
&lt;br /&gt;
'''Stock virtuel'''&lt;br /&gt;
&lt;br /&gt;
Le stock virtuel est la quantité de produit en stock après que les opération affectant les stock sont terminées (réceptions de commandes fournisseurs, expéditions de commandes clients,...)&lt;br /&gt;
&lt;br /&gt;
'''Qty commandes clients'''&lt;br /&gt;
&lt;br /&gt;
Quantité de produit en commandes client ouvertes&lt;br /&gt;
&lt;br /&gt;
'''Qty factures clients'''&lt;br /&gt;
&lt;br /&gt;
Quantité de produit en factures client ouvertes&lt;br /&gt;
&lt;br /&gt;
== Contact ==&lt;br /&gt;
&lt;br /&gt;
Pour toutes questions sur les produits et services, veuillez nous contacter:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Siladel.png|link=https://www.siladel.fr|alt=&amp;quot;hello&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
[https://www.siladel.fr/service/developpement-dolibarr Développement personnalisé Dolibarr]&lt;br /&gt;
&lt;br /&gt;
[https://www.dolistore.com/index.php?controller=search&amp;amp;orderby=position&amp;amp;orderway=desc&amp;amp;tag=&amp;amp;website=marketplace&amp;amp;search_query=siladel Vente en ligne de nos modules]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Addinventory&amp;diff=512</id>
		<title>Addinventory</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Addinventory&amp;diff=512"/>
				<updated>2025-08-30T09:43:26Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : /* Contact */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
ADDINVENTORY est un module Dolibarr permettant de modifier rapidement votre stock à partir d'un liste de produit, lots, déclinaison.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Correction en masse du stock à partir d'une liste (lot et déclinaison compris).&lt;br /&gt;
*Création en masse de lots.&lt;br /&gt;
*Fait gagner du temps lors des mouvements de stocks.&lt;br /&gt;
*Un tableau vous permet d'avoir un aperçu des référents en un coup d'œil.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Pour les version Dolibarr 6 et plus&lt;br /&gt;
*Depuis l'interface à la page Configuration &amp;gt; Modules/Applications Cliquez sur l'onglet Déployer/Installer un module externe.&lt;br /&gt;
&lt;br /&gt;
Une fois l'installation terminé, les pages &amp;quot;Inventaire &amp;amp; correction&amp;quot; et &amp;quot;Stocks référents&amp;quot; seront disponibles dans l'onglet &amp;quot;Produits | services&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
[[Fichier:Conf addinventory2.png|880px]]&lt;br /&gt;
&lt;br /&gt;
'''Activer les quantités décimales :'''&lt;br /&gt;
&lt;br /&gt;
Activez cette fonction pour une gestion du stock basé sur les décimaux.&lt;br /&gt;
&lt;br /&gt;
'''Correction de stock par quantité Delta :'''&lt;br /&gt;
&lt;br /&gt;
Permet de renseigner la quantité totale d'un produit mais la quantité à ajouter ou à supprimer.&lt;br /&gt;
Vous avez alors le choix entre saisir manuellement la quantité à ajouter ou à supprimer en incluant le signe moins - ou utiliser les flèches pour ajuster la quantité.&lt;br /&gt;
&lt;br /&gt;
'''Correction de stock par substitution :'''&lt;br /&gt;
&lt;br /&gt;
Il s'agit simplement de renseigner la quantité totale d'un produit.&lt;br /&gt;
&lt;br /&gt;
'''Proposez aux utilisateurs de choisir le mode (Delta ou par substitution) dans la page &amp;quot;Inventaire &amp;amp; correction&amp;quot; '''&lt;br /&gt;
&lt;br /&gt;
Permet de switcher entre les deux modes aux choix dans la page &amp;quot;Inventaire &amp;amp; correction&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''Rendre possible de modifier le stock sur les produits parents contenant des variants'''&lt;br /&gt;
&lt;br /&gt;
Par défaut Dolibarr ne permet pas de saisir du stock sur les produits parents variants.&lt;br /&gt;
A utiliser dans de cas bien précis, par corriger des erreurs par exemple.&lt;br /&gt;
&lt;br /&gt;
'''Afficher les services '''&lt;br /&gt;
&lt;br /&gt;
Affiche dans la liste tous les produits de type service.&lt;br /&gt;
&lt;br /&gt;
'''Activer la saisie du prix d'achat.'''&lt;br /&gt;
&lt;br /&gt;
Permet de saisir le prix d'achat unitaire de l'ensemble des produits nouvellement ajoutés.&lt;br /&gt;
&lt;br /&gt;
'''Permettre la création de nouveaux lots.'''&lt;br /&gt;
&lt;br /&gt;
Pour chaque produit de type lot, la fonction complète sur une ligne les champs indispensables pour saisir de nouveaux lots. voir l'exemple ci-dessous&lt;br /&gt;
(n° de lot, entrepôt, DLC, DMD/DLUO, prix achat, stock)&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Conf addinventory list.png|900px]]&lt;br /&gt;
&lt;br /&gt;
== Fonctionnement correction du stock ==&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Doc_addinventory.png|880px]]&lt;br /&gt;
&lt;br /&gt;
Pour modifier le stock d'un seul produit, renseignez simplement la quantité totale du produit ou la quantité à ajouter (suivant la méthode définie dans la page configuration) dans le champ de saisie.&lt;br /&gt;
&lt;br /&gt;
'''En mode quantité Delta :'''&lt;br /&gt;
Ce que vous saisissez dans cette entrée est un delta de la quantité, ce qui signifie que ce n'est pas la valeur de stock finale souhaitée, mais la quantité que vous ajoutez ou supprimez. Vous pouvez soit taper la quantité à ajouter ou à supprimer (avec un signe moins), soit utiliser les flèches haut et bas pour ajuster la quantité.&lt;br /&gt;
&lt;br /&gt;
'''En mode par substitution :'''&lt;br /&gt;
Renseignez simplement la quantité totale du produit disponible en stock.&lt;br /&gt;
&lt;br /&gt;
Pour valider le nouveau stock, cliquez simplement sur le bouton &amp;quot;Enregistrer&amp;quot; situé en bas de page.&lt;br /&gt;
&lt;br /&gt;
'''Information !'''&lt;br /&gt;
&lt;br /&gt;
Lors de la recherche avec un entrepôt défini, les produits apparaissent seulement si un stock existe. sinon, vous devrez effectuer une recherche sans définir l’entrepôt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Addinventory_screen04.jpg|880px]]&lt;br /&gt;
&lt;br /&gt;
Pour chaque correction effectuée sur le stock, Dolibarr enregistre un mouvement de stock avec le delta de la quantité positif ou négatif quelle que soit la méthode utilisée (delta ou substitution).&lt;br /&gt;
&lt;br /&gt;
== Page Stocks référents ==&lt;br /&gt;
[[Fichier:Addinventory screen03.jpg|880px]]&lt;br /&gt;
&lt;br /&gt;
'''Stock physique'''&lt;br /&gt;
&lt;br /&gt;
Le stock physique représente la quantité que vous avez réellement physiquement dans votre entrepôt.&lt;br /&gt;
&lt;br /&gt;
'''Stock virtuel'''&lt;br /&gt;
&lt;br /&gt;
Le stock virtuel est la quantité de produit en stock après que les opération affectant les stock sont terminées (réceptions de commandes fournisseurs, expéditions de commandes clients,...)&lt;br /&gt;
&lt;br /&gt;
'''Qty commandes clients'''&lt;br /&gt;
&lt;br /&gt;
Quantité de produit en commandes client ouvertes&lt;br /&gt;
&lt;br /&gt;
'''Qty factures clients'''&lt;br /&gt;
&lt;br /&gt;
Quantité de produit en factures client ouvertes&lt;br /&gt;
&lt;br /&gt;
== Contact ==&lt;br /&gt;
&lt;br /&gt;
Pour toutes questions sur les produits et services, veuillez nous contacter:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Siladel.png|link=https://www.siladel.fr]]&lt;br /&gt;
&lt;br /&gt;
[https://www.siladel.fr/service/developpement-dolibarr Développement personnalisé Dolibarr]&lt;br /&gt;
&lt;br /&gt;
[https://www.dolistore.com/index.php?controller=search&amp;amp;orderby=position&amp;amp;orderway=desc&amp;amp;tag=&amp;amp;website=marketplace&amp;amp;search_query=siladel Vente en ligne de nos modules]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Addinventory&amp;diff=511</id>
		<title>Addinventory</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Addinventory&amp;diff=511"/>
				<updated>2025-08-30T09:42:42Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : /* Contact */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
ADDINVENTORY est un module Dolibarr permettant de modifier rapidement votre stock à partir d'un liste de produit, lots, déclinaison.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Correction en masse du stock à partir d'une liste (lot et déclinaison compris).&lt;br /&gt;
*Création en masse de lots.&lt;br /&gt;
*Fait gagner du temps lors des mouvements de stocks.&lt;br /&gt;
*Un tableau vous permet d'avoir un aperçu des référents en un coup d'œil.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Pour les version Dolibarr 6 et plus&lt;br /&gt;
*Depuis l'interface à la page Configuration &amp;gt; Modules/Applications Cliquez sur l'onglet Déployer/Installer un module externe.&lt;br /&gt;
&lt;br /&gt;
Une fois l'installation terminé, les pages &amp;quot;Inventaire &amp;amp; correction&amp;quot; et &amp;quot;Stocks référents&amp;quot; seront disponibles dans l'onglet &amp;quot;Produits | services&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
[[Fichier:Conf addinventory2.png|880px]]&lt;br /&gt;
&lt;br /&gt;
'''Activer les quantités décimales :'''&lt;br /&gt;
&lt;br /&gt;
Activez cette fonction pour une gestion du stock basé sur les décimaux.&lt;br /&gt;
&lt;br /&gt;
'''Correction de stock par quantité Delta :'''&lt;br /&gt;
&lt;br /&gt;
Permet de renseigner la quantité totale d'un produit mais la quantité à ajouter ou à supprimer.&lt;br /&gt;
Vous avez alors le choix entre saisir manuellement la quantité à ajouter ou à supprimer en incluant le signe moins - ou utiliser les flèches pour ajuster la quantité.&lt;br /&gt;
&lt;br /&gt;
'''Correction de stock par substitution :'''&lt;br /&gt;
&lt;br /&gt;
Il s'agit simplement de renseigner la quantité totale d'un produit.&lt;br /&gt;
&lt;br /&gt;
'''Proposez aux utilisateurs de choisir le mode (Delta ou par substitution) dans la page &amp;quot;Inventaire &amp;amp; correction&amp;quot; '''&lt;br /&gt;
&lt;br /&gt;
Permet de switcher entre les deux modes aux choix dans la page &amp;quot;Inventaire &amp;amp; correction&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''Rendre possible de modifier le stock sur les produits parents contenant des variants'''&lt;br /&gt;
&lt;br /&gt;
Par défaut Dolibarr ne permet pas de saisir du stock sur les produits parents variants.&lt;br /&gt;
A utiliser dans de cas bien précis, par corriger des erreurs par exemple.&lt;br /&gt;
&lt;br /&gt;
'''Afficher les services '''&lt;br /&gt;
&lt;br /&gt;
Affiche dans la liste tous les produits de type service.&lt;br /&gt;
&lt;br /&gt;
'''Activer la saisie du prix d'achat.'''&lt;br /&gt;
&lt;br /&gt;
Permet de saisir le prix d'achat unitaire de l'ensemble des produits nouvellement ajoutés.&lt;br /&gt;
&lt;br /&gt;
'''Permettre la création de nouveaux lots.'''&lt;br /&gt;
&lt;br /&gt;
Pour chaque produit de type lot, la fonction complète sur une ligne les champs indispensables pour saisir de nouveaux lots. voir l'exemple ci-dessous&lt;br /&gt;
(n° de lot, entrepôt, DLC, DMD/DLUO, prix achat, stock)&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Conf addinventory list.png|900px]]&lt;br /&gt;
&lt;br /&gt;
== Fonctionnement correction du stock ==&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Doc_addinventory.png|880px]]&lt;br /&gt;
&lt;br /&gt;
Pour modifier le stock d'un seul produit, renseignez simplement la quantité totale du produit ou la quantité à ajouter (suivant la méthode définie dans la page configuration) dans le champ de saisie.&lt;br /&gt;
&lt;br /&gt;
'''En mode quantité Delta :'''&lt;br /&gt;
Ce que vous saisissez dans cette entrée est un delta de la quantité, ce qui signifie que ce n'est pas la valeur de stock finale souhaitée, mais la quantité que vous ajoutez ou supprimez. Vous pouvez soit taper la quantité à ajouter ou à supprimer (avec un signe moins), soit utiliser les flèches haut et bas pour ajuster la quantité.&lt;br /&gt;
&lt;br /&gt;
'''En mode par substitution :'''&lt;br /&gt;
Renseignez simplement la quantité totale du produit disponible en stock.&lt;br /&gt;
&lt;br /&gt;
Pour valider le nouveau stock, cliquez simplement sur le bouton &amp;quot;Enregistrer&amp;quot; situé en bas de page.&lt;br /&gt;
&lt;br /&gt;
'''Information !'''&lt;br /&gt;
&lt;br /&gt;
Lors de la recherche avec un entrepôt défini, les produits apparaissent seulement si un stock existe. sinon, vous devrez effectuer une recherche sans définir l’entrepôt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Addinventory_screen04.jpg|880px]]&lt;br /&gt;
&lt;br /&gt;
Pour chaque correction effectuée sur le stock, Dolibarr enregistre un mouvement de stock avec le delta de la quantité positif ou négatif quelle que soit la méthode utilisée (delta ou substitution).&lt;br /&gt;
&lt;br /&gt;
== Page Stocks référents ==&lt;br /&gt;
[[Fichier:Addinventory screen03.jpg|880px]]&lt;br /&gt;
&lt;br /&gt;
'''Stock physique'''&lt;br /&gt;
&lt;br /&gt;
Le stock physique représente la quantité que vous avez réellement physiquement dans votre entrepôt.&lt;br /&gt;
&lt;br /&gt;
'''Stock virtuel'''&lt;br /&gt;
&lt;br /&gt;
Le stock virtuel est la quantité de produit en stock après que les opération affectant les stock sont terminées (réceptions de commandes fournisseurs, expéditions de commandes clients,...)&lt;br /&gt;
&lt;br /&gt;
'''Qty commandes clients'''&lt;br /&gt;
&lt;br /&gt;
Quantité de produit en commandes client ouvertes&lt;br /&gt;
&lt;br /&gt;
'''Qty factures clients'''&lt;br /&gt;
&lt;br /&gt;
Quantité de produit en factures client ouvertes&lt;br /&gt;
&lt;br /&gt;
== Contact ==&lt;br /&gt;
&lt;br /&gt;
Pour toutes questions sur les produits et services, veuillez nous contacter:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Siladel.png|link=https://www.siladel.fr]]&lt;br /&gt;
&lt;br /&gt;
[https://www.siladel.fr/service/developpement-dolibarr Développement personnalisé Dolibarr]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://www.dolistore.com/index.php?controller=search&amp;amp;orderby=position&amp;amp;orderway=desc&amp;amp;tag=&amp;amp;website=marketplace&amp;amp;search_query=siladel Vente en ligne de nos modules]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Viewmap&amp;diff=510</id>
		<title>Viewmap</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Viewmap&amp;diff=510"/>
				<updated>2025-08-30T09:41:20Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : /* Contact */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Le module Viewmap permet de géolocaliser vos différents tiers, tels que les prospects, les clients, les fournisseurs, les contacts et les adhérents, sur une carte Google Maps. En effet, lors de la création d'un nouveau tiers, ce module effectue automatiquement la géolocalisation de son adresse et vous offre la capacité d'afficher l'ensemble de vos tiers sur une carte unique.&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Depuis l'interface à la page Configuration &amp;gt; Modules/Applications Cliquez sur l'onglet Déployer/Installer un module externe.&lt;br /&gt;
&lt;br /&gt;
Après avoir terminé l'installation, rendez-vous sur la page de configuration pour saisir votre clé Google Map.&lt;br /&gt;
&lt;br /&gt;
La carte sera accessible depuis l'onglet &amp;quot;outils&amp;quot; et également sur les fiches de vos tiers.&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
Une fois l'installation du module terminée dans l'application Dolibarr, vous devez activer le module qui se trouve dans la session Modules/Applications&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Viewmap index.jpg| 900px ]]&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Viewmap screen config.jpg|900px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Test du géocodage pendant le processus de création'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Vous pouvez tester de géolocaliser une adresse postale pendant la saisie d'un nouveau tiers avec l'option &amp;quot;Test du géocodage pendant le processus de création&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Clé Google Map'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;&lt;br /&gt;
Pour afficher une carte Google Maps sur votre Dolibarr, il est nécessaire de spécifier une clé d'API. Nous allons voir dans ce tutoriel comment l'obtenir et l'utiliser dans votre module Viwmap.&lt;br /&gt;
&lt;br /&gt;
Pour être en mesure d'obtenir une clé d'API, il est nécessaire de disposer au préalable d'un compte Gmail. Si ce n'est pas votre cas, vous devez en créer un au préalable.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Zoom de la fiche client et de la carte '''&lt;br /&gt;
&lt;br /&gt;
Vous pouvez modifier le zoom des cartes. &lt;br /&gt;
*1 = Le monde entier&lt;br /&gt;
*6 = La France entière &lt;br /&gt;
*11 = un département&lt;br /&gt;
*16 = un quartier&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Clusterisation des marqueurs sur la carte principale'''&lt;br /&gt;
&lt;br /&gt;
Cette fonction permet de regrouper les markers en zone.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Géocodage en masse de vos contacts'''&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Geocodage_setting.png]]&lt;br /&gt;
&lt;br /&gt;
Pour chaque clic sur le bouton &amp;quot;géocoder&amp;quot; vous effectuez un géocodage sur 100 adresses. &lt;br /&gt;
&lt;br /&gt;
Appuyez sur autant de fois que nécessaire pour géocoder l'ensemble de vos contacts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;&lt;br /&gt;
L'utilisation de l'API Google Geocoding est limitée par un quota de 2.500 requêtes de géolocalisation par jour.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''' Effacer les données du géocodage'''&lt;br /&gt;
&lt;br /&gt;
Cette fonction supprimer les coordonnées GPS de tous vos société/contacts.&lt;br /&gt;
&lt;br /&gt;
''' Définir ses propres marqueurs '''&lt;br /&gt;
&lt;br /&gt;
Le module propose de remplacer les marqueurs par défaut suivant le type de tier.&lt;br /&gt;
&lt;br /&gt;
il est recommandé d'utiliser des images de 48px maximum au format PNG, GIF, JPG&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Viewmap marqueurs.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Obtenir une clé d'API Google Map:==&lt;br /&gt;
&lt;br /&gt;
Pour obtenir cette clé, vous devez vous rendre sur [https://console.developers.google.com/flows/enableapi?apiid=maps_backend&amp;amp;keyType=CLIENT_SIDE&amp;amp;reusekey=true&amp;amp;hl=fr&amp;amp;pli=1 console.developers.google.com]&lt;br /&gt;
&lt;br /&gt;
===1. Création d'un nouveau projet===&lt;br /&gt;
&lt;br /&gt;
S'il s'agit de votre première connexion sur la console, vous allez automatiquement créer un nouveau projet qui sera nommé &amp;quot;My Projet&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Il suffit de cocher 2 cases :&lt;br /&gt;
&lt;br /&gt;
*indiquez si vous souhaitez recevoir ou non l'actualité Google APIs &lt;br /&gt;
*acceptez les conditions d'utilisation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===2. Création de la clé===&lt;br /&gt;
&lt;br /&gt;
*Vous devez nommer la clé ou laisser le nom par défaut &amp;quot;Clé API 1&amp;quot;&lt;br /&gt;
*Pour sécuriser votre clé, appliquez une restriction en choisissant &amp;quot;Adresse IP&amp;quot; et entrez l'adresse IP de votre serveur Dolibarr. Ainsi, seule cette adresse sera autorisée à utiliser la clé.&lt;br /&gt;
*Assurez-vous d'associer à votre clé les API suivantes : &amp;quot;Maps JavaScript API&amp;quot; et &amp;quot;Geocoding API&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Depuis le 11 juin 2018, il est obligatoire d’activer un compte de facturation afin de pouvoir utiliser les services Google Maps.&lt;br /&gt;
Toutefois, Google fournit généralement un crédit gratuit mensuel, ce qui signifie que pour une utilisation modérée, il n'y a souvent pas de frais réels à payer.&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;&lt;br /&gt;
Important : Viewmap fait appel à l'API de géocodage uniquement une seule fois lors de la géolocalisation de l'adresse.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Poursuivez en cliquant sur &amp;quot;Créer&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===3. Votre clé a été créée===&lt;br /&gt;
Une nouvelle fenêtre s'affiche avec votre clé d'API. Copiez-la pour l'intégrer dans votre configuration Viewmap.&lt;br /&gt;
&lt;br /&gt;
== Utilisation ==&lt;br /&gt;
&lt;br /&gt;
=== Carte sur la fiche client ===&lt;br /&gt;
&lt;br /&gt;
Géocoder une adresse postale sur la fiche d'un tiers :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Viewmaptier.jpg | 700px]]&lt;br /&gt;
&lt;br /&gt;
=== Option d'affichage ===&lt;br /&gt;
&lt;br /&gt;
Contrôle des données lorsque vous utilisez l'API Viewmap.&lt;br /&gt;
&lt;br /&gt;
Pour le tier en cours, vous pouvez choisir de masquer certaine information comme l’e-mail, téléphone, Url ou ne rien afficher.&lt;br /&gt;
&lt;br /&gt;
(cette fonctionnalité est prise en compte uniquement avec l'API Viewmap)&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Viewmap option api.jpg | 900px]]&lt;br /&gt;
&lt;br /&gt;
=== Carte d'ensemble ===&lt;br /&gt;
&lt;br /&gt;
Dans Outils, une carte est disponible pour visualiser l'ensemble des tiers.&lt;br /&gt;
&lt;br /&gt;
Vous pouvez filtrer vos données par type de tier, pays, département, catégorie ou par commerciaux&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Viewmap map2.jpg | 900px]]&lt;br /&gt;
&lt;br /&gt;
== Contact ==&lt;br /&gt;
&lt;br /&gt;
Pour toutes questions sur les produits et services, veuillez nous contacter:&lt;br /&gt;
&lt;br /&gt;
[https://www.siladel.fr/service/developpement-dolibarr Développement personnalisé Dolibarr]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Viewmap&amp;diff=509</id>
		<title>Viewmap</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Viewmap&amp;diff=509"/>
				<updated>2025-08-30T09:40:49Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : /* Contact */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Le module Viewmap permet de géolocaliser vos différents tiers, tels que les prospects, les clients, les fournisseurs, les contacts et les adhérents, sur une carte Google Maps. En effet, lors de la création d'un nouveau tiers, ce module effectue automatiquement la géolocalisation de son adresse et vous offre la capacité d'afficher l'ensemble de vos tiers sur une carte unique.&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Depuis l'interface à la page Configuration &amp;gt; Modules/Applications Cliquez sur l'onglet Déployer/Installer un module externe.&lt;br /&gt;
&lt;br /&gt;
Après avoir terminé l'installation, rendez-vous sur la page de configuration pour saisir votre clé Google Map.&lt;br /&gt;
&lt;br /&gt;
La carte sera accessible depuis l'onglet &amp;quot;outils&amp;quot; et également sur les fiches de vos tiers.&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
Une fois l'installation du module terminée dans l'application Dolibarr, vous devez activer le module qui se trouve dans la session Modules/Applications&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Viewmap index.jpg| 900px ]]&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Viewmap screen config.jpg|900px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Test du géocodage pendant le processus de création'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Vous pouvez tester de géolocaliser une adresse postale pendant la saisie d'un nouveau tiers avec l'option &amp;quot;Test du géocodage pendant le processus de création&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Clé Google Map'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;&lt;br /&gt;
Pour afficher une carte Google Maps sur votre Dolibarr, il est nécessaire de spécifier une clé d'API. Nous allons voir dans ce tutoriel comment l'obtenir et l'utiliser dans votre module Viwmap.&lt;br /&gt;
&lt;br /&gt;
Pour être en mesure d'obtenir une clé d'API, il est nécessaire de disposer au préalable d'un compte Gmail. Si ce n'est pas votre cas, vous devez en créer un au préalable.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Zoom de la fiche client et de la carte '''&lt;br /&gt;
&lt;br /&gt;
Vous pouvez modifier le zoom des cartes. &lt;br /&gt;
*1 = Le monde entier&lt;br /&gt;
*6 = La France entière &lt;br /&gt;
*11 = un département&lt;br /&gt;
*16 = un quartier&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Clusterisation des marqueurs sur la carte principale'''&lt;br /&gt;
&lt;br /&gt;
Cette fonction permet de regrouper les markers en zone.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Géocodage en masse de vos contacts'''&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Geocodage_setting.png]]&lt;br /&gt;
&lt;br /&gt;
Pour chaque clic sur le bouton &amp;quot;géocoder&amp;quot; vous effectuez un géocodage sur 100 adresses. &lt;br /&gt;
&lt;br /&gt;
Appuyez sur autant de fois que nécessaire pour géocoder l'ensemble de vos contacts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;&lt;br /&gt;
L'utilisation de l'API Google Geocoding est limitée par un quota de 2.500 requêtes de géolocalisation par jour.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''' Effacer les données du géocodage'''&lt;br /&gt;
&lt;br /&gt;
Cette fonction supprimer les coordonnées GPS de tous vos société/contacts.&lt;br /&gt;
&lt;br /&gt;
''' Définir ses propres marqueurs '''&lt;br /&gt;
&lt;br /&gt;
Le module propose de remplacer les marqueurs par défaut suivant le type de tier.&lt;br /&gt;
&lt;br /&gt;
il est recommandé d'utiliser des images de 48px maximum au format PNG, GIF, JPG&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Viewmap marqueurs.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Obtenir une clé d'API Google Map:==&lt;br /&gt;
&lt;br /&gt;
Pour obtenir cette clé, vous devez vous rendre sur [https://console.developers.google.com/flows/enableapi?apiid=maps_backend&amp;amp;keyType=CLIENT_SIDE&amp;amp;reusekey=true&amp;amp;hl=fr&amp;amp;pli=1 console.developers.google.com]&lt;br /&gt;
&lt;br /&gt;
===1. Création d'un nouveau projet===&lt;br /&gt;
&lt;br /&gt;
S'il s'agit de votre première connexion sur la console, vous allez automatiquement créer un nouveau projet qui sera nommé &amp;quot;My Projet&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Il suffit de cocher 2 cases :&lt;br /&gt;
&lt;br /&gt;
*indiquez si vous souhaitez recevoir ou non l'actualité Google APIs &lt;br /&gt;
*acceptez les conditions d'utilisation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===2. Création de la clé===&lt;br /&gt;
&lt;br /&gt;
*Vous devez nommer la clé ou laisser le nom par défaut &amp;quot;Clé API 1&amp;quot;&lt;br /&gt;
*Pour sécuriser votre clé, appliquez une restriction en choisissant &amp;quot;Adresse IP&amp;quot; et entrez l'adresse IP de votre serveur Dolibarr. Ainsi, seule cette adresse sera autorisée à utiliser la clé.&lt;br /&gt;
*Assurez-vous d'associer à votre clé les API suivantes : &amp;quot;Maps JavaScript API&amp;quot; et &amp;quot;Geocoding API&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Depuis le 11 juin 2018, il est obligatoire d’activer un compte de facturation afin de pouvoir utiliser les services Google Maps.&lt;br /&gt;
Toutefois, Google fournit généralement un crédit gratuit mensuel, ce qui signifie que pour une utilisation modérée, il n'y a souvent pas de frais réels à payer.&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;&lt;br /&gt;
Important : Viewmap fait appel à l'API de géocodage uniquement une seule fois lors de la géolocalisation de l'adresse.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Poursuivez en cliquant sur &amp;quot;Créer&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===3. Votre clé a été créée===&lt;br /&gt;
Une nouvelle fenêtre s'affiche avec votre clé d'API. Copiez-la pour l'intégrer dans votre configuration Viewmap.&lt;br /&gt;
&lt;br /&gt;
== Utilisation ==&lt;br /&gt;
&lt;br /&gt;
=== Carte sur la fiche client ===&lt;br /&gt;
&lt;br /&gt;
Géocoder une adresse postale sur la fiche d'un tiers :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Viewmaptier.jpg | 700px]]&lt;br /&gt;
&lt;br /&gt;
=== Option d'affichage ===&lt;br /&gt;
&lt;br /&gt;
Contrôle des données lorsque vous utilisez l'API Viewmap.&lt;br /&gt;
&lt;br /&gt;
Pour le tier en cours, vous pouvez choisir de masquer certaine information comme l’e-mail, téléphone, Url ou ne rien afficher.&lt;br /&gt;
&lt;br /&gt;
(cette fonctionnalité est prise en compte uniquement avec l'API Viewmap)&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Viewmap option api.jpg | 900px]]&lt;br /&gt;
&lt;br /&gt;
=== Carte d'ensemble ===&lt;br /&gt;
&lt;br /&gt;
Dans Outils, une carte est disponible pour visualiser l'ensemble des tiers.&lt;br /&gt;
&lt;br /&gt;
Vous pouvez filtrer vos données par type de tier, pays, département, catégorie ou par commerciaux&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Viewmap map2.jpg | 900px]]&lt;br /&gt;
&lt;br /&gt;
== Contact ==&lt;br /&gt;
&lt;br /&gt;
Pour toutes questions sur les produits et services, veuillez nous contacter:&lt;br /&gt;
&lt;br /&gt;
[[link=https://www.siladel.fr/service/developpement-dolibarr|Développement de modules Dolibarr]]&lt;br /&gt;
&lt;br /&gt;
[https://www.siladel.fr/service/developpement-dolibarr Développement personnalisé Dolibarr]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Exportpresta&amp;diff=508</id>
		<title>Exportpresta</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Exportpresta&amp;diff=508"/>
				<updated>2025-04-12T03:04:37Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : /* Contact */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
ExportPresta est une solution (développée par [https://www.siladel.fr/ Siladel : Agence web Albi]) permettant d'aider les utilisateurs à exporter leurs produits Dolibarr vers PrestaShop.&lt;br /&gt;
&lt;br /&gt;
Ce module permet de générer des fichiers CSV compatibles avec PrestaShop.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ExportPresta comprend 3 méthodes d'exportations différentes permettant de répondre au mieux à chaque situation.&lt;br /&gt;
&lt;br /&gt;
Méthodes à partir du Core (Dolibarr 7+), méthode par référence, méthode par définition d'un SKU personnalisé avec définition d'attributs.&lt;br /&gt;
&lt;br /&gt;
*Exporte les produits simples ou déclinés.&lt;br /&gt;
*Exporte les images, attributs, catégories, codeb-arres[EAN13, UPS, ISBN], stock, prix de vos produits et déclinaisons&lt;br /&gt;
*Exporte selon vos catégories, entrepôts, stocks.&lt;br /&gt;
*Ajustement du prix final.&lt;br /&gt;
*Exporte vos impacts sur le prix et le poids&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Décompressez le fichier dans le dossier &amp;quot;htdocs/custom&amp;quot; ou à la racine htdocs/ (suivant votre configuration)&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
'''Mode à partir du core de Dolibarr v7+'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Rien à saisir dans ce mode. Les attributs sont générés avec le module par défaut &amp;quot;Variante Produit&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Avant de générer vos fichiers CSV, il ne faudra pas oublier d'activer l'option &amp;quot;Rendre accessible les images des produits pour PrestaShop&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Cela générera les liens dans vos fichiers pour que PrestaShop puisse ensuite trouver les images.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:prest_conf01.png]]&lt;br /&gt;
&lt;br /&gt;
'''Mode à partir d'une référence produit.'''&lt;br /&gt;
&lt;br /&gt;
Ce mode est pour vous si les références de vos déclinaisons possèdent un caractère de séparation et que vous n'utilisez pas le module par défaut&lt;br /&gt;
&amp;quot;Variante de produits &amp;quot; ou que votre version de Dolibarr est inférieure à la version 7.&lt;br /&gt;
&lt;br /&gt;
Avant de générer vos fichiers CSV, il ne faudra pas oublier d'activer l'option &amp;quot;Rendre accessible les images des produits pour PrestaShop&amp;quot;&lt;br /&gt;
&lt;br /&gt;
cela générera les liens dans vos fichiers pour que PrestaShop puisse ensuite trouver les images.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:prest_conf02.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Mode à partir d'un SKU personnalisé'''&lt;br /&gt;
&lt;br /&gt;
Vous pouvez activer ce mode, dans le cas où vos produits sont créés avec un SKU (une référence de famille produit) à l'aide des &amp;quot;champs personnalisés&amp;quot; du module &amp;quot;Produits&amp;quot; et que vous possédez des attributs supplémentaires comme par exemple(taille, couleur, modèle) sur tous vos produits.&lt;br /&gt;
&lt;br /&gt;
Avant de générer vos fichiers CSV, il ne faudra pas oublier d'activer l'option &amp;quot;Rendre accessible les images des produits pour PrestaShop&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Cela générera les liens dans vos fichiers pour que PrestaShop puisse ensuite trouver les images. &lt;br /&gt;
&lt;br /&gt;
[[Fichier:Conf03.png]]&lt;br /&gt;
&lt;br /&gt;
== Utilisation ==&lt;br /&gt;
&lt;br /&gt;
Pour afficher la page ci-dessous vous devez vous rendre sur l'onglet '''Outils''' puis '''Export Prestashop'''&lt;br /&gt;
&lt;br /&gt;
Cette page permet de générer un fichier CSV de vos produits sans les déclinaisons.&lt;br /&gt;
&lt;br /&gt;
===1. Paramètres de sélection pour Dolibarr ===&lt;br /&gt;
Cette zone sert à sélectionner les produits dont vous avez besoin.&lt;br /&gt;
&lt;br /&gt;
*Tag/catégorie pour les produits liés à une catégorie.&lt;br /&gt;
*L'entrepôt.(A condition d'avoir du stock dans l'entrepôt).&lt;br /&gt;
*Uniquement les produits en vente (tagués en Vente sur la fiche produit).&lt;br /&gt;
*Uniquement les produits en stock.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===2. Paramètres d'importation pour PrestaShop ===&lt;br /&gt;
Cette zone sert à ajouter des propriétés utiles dans votre fichier CSV. Elles seront ensuite prises en compte sous PrestaShop.&lt;br /&gt;
&lt;br /&gt;
*Taux de marge ; Pour effectuer un ajustement du prix final.&lt;br /&gt;
*Id boutique ; Identifiant de la boutique PrestaShop (laissez vide, si vous ne gérez qu’une seule boutique).&lt;br /&gt;
*Qty en fonction du stock ; Pour utiliser la quantité définie par l'entrepôt.&lt;br /&gt;
*Gestion des stocks Avancés ; Active la gestion des stocks avancés sur tous les produits.&lt;br /&gt;
*Uniquement en ligne ; Produit tagué &amp;quot;exclusivement en ligne&amp;quot; pour le client final.&lt;br /&gt;
*Effacer les images existantes ; Activez cette fonction pour remplacer les images des produits par celle du fichier.&lt;br /&gt;
*Identifiant TVA ; généralement sur 1. (TVA 20%)&lt;br /&gt;
*En vente ; Produit en vente sous PrestaShop&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
[[Fichier:Screenshot_exportpresta.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Attention''' !&lt;br /&gt;
&lt;br /&gt;
'''Ce module n'est pas parfait et parfois, l'exportation peut donner un résultat incomplet.'''&lt;br /&gt;
&lt;br /&gt;
'''Dans ce cas, les corrections doivent être réalisées manuellement à l'aide du logiciel LibreOffice ou Microsoft Excel.'''&lt;br /&gt;
&lt;br /&gt;
== Contact ==&lt;br /&gt;
&lt;br /&gt;
Pour toutes questions sur les produits et services, veuillez nous contacter:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[link=https://www.siladel.fr/service/developpement-prestashop|Développement de modules Prestashop]]&lt;br /&gt;
&lt;br /&gt;
[[link=https://www.dolistore.com/index.php?controller=search&amp;amp;orderby=position&amp;amp;orderway=desc&amp;amp;tag=&amp;amp;website=marketplace&amp;amp;search_query=siladel|Vente en ligne de nos modules]]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Addremise&amp;diff=507</id>
		<title>Addremise</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Addremise&amp;diff=507"/>
				<updated>2025-04-12T03:03:56Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : /* Contact */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Module permettant de saisir une remise globale en pourcentage lors de la création de devis, commandes et factures.&lt;br /&gt;
&lt;br /&gt;
ADDRemise inclut la gestion des permissions utilisateurs, la configuration des libellés ainsi que la prise en charge de la TVA.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Déployez un module externe en utilisant l'assistant d'installation disponible dans Configuration &amp;gt; Modules &amp;amp; Applications.&lt;br /&gt;
&lt;br /&gt;
Vous pouvez également décompressez le fichier dans le dossier &amp;quot;htdocs/custom&amp;quot; ou à la racine htdocs/&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
&lt;br /&gt;
Une fois le module installé, vous devez l'activer dans l'application Dolibarr via la session &amp;quot;Modules/Applications&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Conf.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Les paramètres de configurations ==&lt;br /&gt;
&lt;br /&gt;
[[Fichier:addremise_setting1.7.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Paramétrage d'activation ===&lt;br /&gt;
Choisissez d'activer ou non Addremise pour les devis, commandes, factures.&lt;br /&gt;
&lt;br /&gt;
=== Libellés des remises globales par défaut ===&lt;br /&gt;
Permet d'ajouter une description à votre remise après le pourcentage.&lt;br /&gt;
par exemple par défaut 10% &amp;quot;de remise client&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Paramètres additionnels : ===&lt;br /&gt;
*'''Affiche la ligne remise globale dans la liste des produits :'''&lt;br /&gt;
**Activez cette option si vous voulez faire apparaitre la remise globale en même temps que la liste des produits&lt;br /&gt;
&lt;br /&gt;
*'''Ne pas comptabiliser les produits offerts en tant que remise.'''&lt;br /&gt;
**Par défaut sur Dolibarr, les remises 100% appliquées sur les produits donc gratuit sont comptabilisées en tant que remise.&lt;br /&gt;
**Vous pouvez désactiver cette option pour ne pas comptabiliser les produits gratuit ou offert en tant que remise.&lt;br /&gt;
&lt;br /&gt;
*'''Afficher les produits offerts sur la même ligne que les produits vendus.'''&lt;br /&gt;
**Il s’agit de regrouper les produits de même référence offert ou pas sur une ligne.&lt;br /&gt;
&lt;br /&gt;
*'''Ne pas afficher le taux des remises dans les totaux.'''&lt;br /&gt;
**désactive le pourcentage de remise dans les totaux. &amp;quot;Total remise&amp;quot; ou &amp;quot;Total remise (5%)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*'''Ne pas afficher la colonne TVA dans le PDF.'''&lt;br /&gt;
**Permet simplement de ne pas afiicher la colonne TVA dans le tableau des produits.&lt;br /&gt;
**N'activer cette option si vous avez plusieurs taux de TVA.&lt;br /&gt;
&lt;br /&gt;
== Permissions et droits d’accès ==&lt;br /&gt;
Par défaut les permissions sont activées pour l'administrateur. &lt;br /&gt;
Pour gérer les permissions en rapport avec le module, allez dans le menu &amp;quot;Utilisateurs &amp;amp; Groupes&amp;quot;, sélectionnez un utilisateur ou un groupe puis l'onglet &amp;quot;permissions utilisateur&amp;quot; ou &amp;quot;permissions groupe&amp;quot; dans le cas d'un groupe.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:permit.jpg]]&lt;br /&gt;
&lt;br /&gt;
== Activer modèle facture PDF avec remise ==&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Screen pdf.jpg|800px]]&lt;br /&gt;
&lt;br /&gt;
Pour activer le modèle crabe en PDF avec les remises dans les totaux, vous devez vous rendre dans la configuration du module '''Factures et avoirs''' qui se trouve dans la session Modules/Applications.&lt;br /&gt;
&lt;br /&gt;
* La remise dans les totaux s'affiche également lorsque vous appliquez une remise standard (remise sur ligne de produit).&lt;br /&gt;
* Vous pouvez additionner les remises sur ligne produit et une remise globale.&lt;br /&gt;
&lt;br /&gt;
== Utilisation ==&lt;br /&gt;
Après installation et activation des remises pour les factures.&lt;br /&gt;
&lt;br /&gt;
Un bouton remise doit apparaître pendant la saisie de votre facture.&lt;br /&gt;
Vous décidez d'ajouter une remise, vous appuyez sur le bouton remise, une fenêtre s'affiche, dans la partie 1, vous saisissez votre pourcentage. Par exemple, le chiffre 10 pour 10%, dans la partie 2, vous saisissez votre texte, dans la partie 3, votre TVA.&lt;br /&gt;
&lt;br /&gt;
Normalement, sauf cas exceptionnel, vous ne devez pas modifier la TVA de votre remise, la remise doit avoir le même taux de TVA que les produits.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Comportement de la remise lorsque vous ajoutez un produit après avoir intégré une remise globale'''&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: red&amp;quot;&amp;gt;&lt;br /&gt;
La remise globale appliquée sur un document se mettra à jour automatiquement après modification.&lt;br /&gt;
Une seule remise globale peut être appliquée par document.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Contact ==&lt;br /&gt;
&lt;br /&gt;
Pour toutes questions sur les produits et services, veuillez nous contacter:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Siladel.png|link=https://www.siladel.fr]]&lt;br /&gt;
&lt;br /&gt;
[[link=https://www.siladel.fr/service/developpement-dolibarr|Développement de modules Dolibarr]]&lt;br /&gt;
&lt;br /&gt;
[[link=https://www.dolistore.com/index.php?controller=search&amp;amp;orderby=position&amp;amp;orderway=desc&amp;amp;tag=&amp;amp;website=marketplace&amp;amp;search_query=siladel|Vente en ligne de nos modules]]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	<entry>
		<id>https://wiki.siladel.fr/index.php?title=Eanprodoc&amp;diff=506</id>
		<title>Eanprodoc</title>
		<link rel="alternate" type="text/html" href="https://wiki.siladel.fr/index.php?title=Eanprodoc&amp;diff=506"/>
				<updated>2025-04-12T03:03:39Z</updated>
		
		<summary type="html">&lt;p&gt;Goldron : /* Contact */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;EANPRODOC est un module Dolibarr permettant d'afficher les codes-barres de vos produits dans vos documents PDF.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Affichez les codes-barres de vos produits dans vos documents PDF (clients et fournisseurs).&lt;br /&gt;
* Insérez automatiquement vos codes produits dans vos factures, commandes et fiches d'expédition.&lt;br /&gt;
* Compatible avec tous les modèles PDF.&lt;br /&gt;
* Prend en charge tous les codes 1D (EAN8, EAN13, EAN128, GS1, ISBN, UPC).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Pour les version Dolibarr 6 et plus&lt;br /&gt;
*Depuis l'interface à la page Configuration &amp;gt; Modules/Applications Cliquez sur l'onglet Déployer/Installer un module externe.&lt;br /&gt;
&lt;br /&gt;
Après avoir terminé l'installation, rendez-vous sur la page de configuration du module pour activer les options de votre choix.&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
[[fichier:Config-eanprodoc.png|880px]]&lt;br /&gt;
&lt;br /&gt;
'''Affiche les codes-barres pour les factures.'''&lt;br /&gt;
Si un produit possède un code-barre, celui-ci sera affiché sur votre facture en PDF.&lt;br /&gt;
&lt;br /&gt;
'''Affiche les codes-barres pour les commandes.'''&lt;br /&gt;
Si un produit possède un code-barre, celui-ci sera visible sur votre bon de commande en PDF.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Affiche les codes-barres pour les fiches d'expéditions.'''&lt;br /&gt;
Si un produit possède un code-barre, celui-ci sera visible sur vos fiches d'expéditions en PDF.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Affiche les codes-barres pour les factures fournisseurs. '''&lt;br /&gt;
Si un produit possède un code-barre, celui-ci sera affiché sur votre facture fournisseur en PDF.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Affiche les codes-barres pour les commandes fournisseurs '''&lt;br /&gt;
Si un produit possède un code-barre, celui-ci sera visible sur votre bon de commande fournisseur en PDF.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Exclure le template commençant par : '''&lt;br /&gt;
permet d'indiquer le nom d'un modèle PDF dans lequel les codes-barres ne seront pas affichés.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Afficher la description sous le code-barres'''&lt;br /&gt;
Affiche le numero du code sous le code barre.&lt;br /&gt;
&lt;br /&gt;
[[fichier:Num_code_eanprodoc.png|800px]]&lt;br /&gt;
&lt;br /&gt;
'''Afficher la description sous le code-barres.'''&lt;br /&gt;
permet un retour à la ligne dans la description au niveau du code-barre.&lt;br /&gt;
&lt;br /&gt;
'''Largeur et Hauteur du code-barres, Largeur de la description'''&lt;br /&gt;
permet un positionnement précis du code-barres dans le document PDF.&lt;br /&gt;
&lt;br /&gt;
== Contact ==&lt;br /&gt;
&lt;br /&gt;
Pour toutes questions sur les produits et services, veuillez nous contacter:&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Siladel.png|link=https://www.siladel.fr]]&lt;br /&gt;
&lt;br /&gt;
[[link=https://www.siladel.fr/service/developpement-dolibarr|Développement de modules Dolibarr]]&lt;br /&gt;
&lt;br /&gt;
[[link=https://www.dolistore.com/index.php?controller=search&amp;amp;orderby=position&amp;amp;orderway=desc&amp;amp;tag=&amp;amp;website=marketplace&amp;amp;search_query=siladel|Vente en ligne de nos modules]]&lt;/div&gt;</summary>
		<author><name>Goldron</name></author>	</entry>

	</feed>