Si votre entreprise utilise déjà une autre plateforme agréée pour la facturation électronique, vous n'êtes pas obligé d'utiliser B2Brouter.
Vous pouvez continuer à générer vos factures dans Zoho Invoice ou Zoho Books, les exporter au format Factur-X, puis les transmettre à votre propre plateforme agréée.
Le fonctionnement est alors le suivant :
Eventmaker → Zoho Invoice / Zoho Books → Factur-X → votre plateforme agréée
Dans cette configuration, Zoho sert à générer et finaliser les factures. La transmission réglementaire est ensuite gérée par votre plateforme externe. Zoho Books confirme explicitement qu'une autre plateforme agréée peut être utilisée à la place de B2Brouter.
1. Zoho Invoice ou Zoho Books ?
Les deux solutions permettent de générer des factures et de les exporter au format Factur-X.
La principale différence concerne l'export en masse :
Fonctionnalité | Zoho Invoice | Zoho Books |
Export Factur-X | ✅ | ✅ |
Export Factur-X depuis l'interface | ✅ | ✅ |
Bulk export Factur-X natif | ❌ Non documenté | ❌ Non documenté |
Bulk export Factur-X automatisé | ❌ Non documenté | ✅ Via script/API |
Utilisation d'une autre plateforme agréée | ✅ | ✅ |
Zoho Invoice dispose bien d'un export de factures en masse via API, mais cet export produit un PDF classique, et non plusieurs fichiers Factur-X. L'API documente actuellement un maximum de 25 factures par export PDF.
Avec Zoho Books, l'export Factur-X en masse peut être automatisé grâce à un script Deluge utilisant les API Zoho Books. Le script fourni par Zoho est disponible en annexe de cette documentation.
2. Prérequis
Votre organisation Zoho doit être configurée pour la France.
Si elle utilise encore l'édition Global, consultez la documentation :
Migrer Zoho Invoice / Zoho Books vers l'édition France
Avant de générer vos Factur-X, vérifiez notamment :
le nom ou la raison sociale ;
l'adresse complète de facturation ;
le pays ;
le SIRET pour les entreprises françaises lorsque nécessaire ;
le numéro de TVA lorsqu'il est applicable.
Si les factures sont générées depuis Eventmaker, vérifiez également le mapping configuré dans le bloc Facturation Zoho.
3. Ne pas transmettre les factures via B2Brouter
Si votre plateforme agréée externe doit gérer la transmission de vos factures, vous ne devez pas utiliser le workflow d'envoi B2Brouter dans Zoho.
Zoho Invoice
Si l'E-Invoicing natif a déjà été activé, rendez-vous dans :
Settings > E-Invoicing
puis cliquez sur :
Disable
Zoho indique explicitement que l'E-Invoicing peut être désactivé lorsqu'une autre plateforme agréée est utilisée pour les factures sortantes.
Zoho Books
Dans :
Settings > Taxes & Compliance > E-Invoicing
désactivez :
Push sales transactions
si vous ne souhaitez pas transmettre vos factures clients via B2Brouter.
Si B2Brouter ne doit pas être utilisé du tout, n'activez pas non plus la récupération des factures fournisseurs via Fetch purchase transactions.
4. Finaliser les factures avant l'export
Dans l'édition France, une facture est d'abord créée au statut :
Draft
Elle doit ensuite être passée au statut :
Open
C'est à ce moment que le numéro définitif de la facture est attribué.
Zoho précise qu'une facture doit être Open avant certaines opérations, notamment la génération Factur-X via API.
Si une facture reste en Draft, vérifiez les informations de facturation avant de poursuivre.
5. Exporter un Factur-X avec Zoho Books
Dans Zoho Books :
Sales > Invoices
ou :
Sales > Credit Notes
Puis :
ouvrez la facture ou l'avoir ;
cliquez sur PDF/Print ;
sélectionnez Factur-X.
Zoho Books génère alors un fichier PDF/A-3 contenant également les données XML structurées. Cette fonctionnalité est disponible pour les organisations dont la localisation est configurée sur la France.
6. Exporter un Factur-X avec Zoho Invoice
Zoho Invoice prend également en charge l'export des factures au format Factur-X.
Ouvrez la facture finalisée dans Zoho Invoice puis utilisez l'option d'export Factur-X disponible sur la facture.
Le fichier peut ensuite être transmis à votre plateforme agréée.
Vérifiez au préalable que votre plateforme externe accepte le profil Factur-X généré par Zoho Invoice.
7. Exporter plusieurs Factur-X
Zoho Invoice
Zoho ne documente actuellement pas de fonctionnalité permettant de générer plusieurs Factur-X en une seule opération dans Zoho Invoice.
L'API propose bien un Bulk export Invoices, mais celui-ci exporte plusieurs factures dans un PDF standard et ne correspond pas à un bulk export Factur-X.
Pour un besoin important d'export Factur-X en masse, Zoho Books est donc actuellement plus adapté.
Zoho Books
Zoho Books ne propose pas de bouton natif permettant d'exporter plusieurs transactions directement en Factur-X.
En revanche, Zoho a fourni un script Deluge permettant d'automatiser ce processus.
Ce script :
récupère une liste de factures ;
ignore les factures Draft et Void ;
génère un Factur-X pour chaque facture ;
peut traiter plusieurs factures au cours d'une même exécution ;
peut envoyer les fichiers par email ;
ou les envoyer directement vers un endpoint HTTP externe.
Le script est reproduit dans l'Annexe — Bulk export Factur-X avec Zoho Books.
8. Configurer le bulk export dans Zoho Books
Créer une connexion
Dans Zoho Books, rendez-vous dans :
Settings > Developer Space > Connections > New Connection
Sélectionnez Zoho Books puis créez une connexion avec le scope :
ZohoBooks.invoices.READ
Conservez le Connection Link Name, qui devra être ajouté au script.
Créer une planification
Rendez-vous ensuite dans :
Settings > Automation > Workflow Actions > Schedules
Créez une nouvelle planification, par exemple :
Factur-X Bulk Export
Ajoutez ensuite le script Deluge fourni en annexe.
Paramètres à modifier
Avant la première exécution, renseignez notamment :
org: identifiant de votre organisation Zoho Books ;mailto: adresse de réception des Factur-X ;YOUR_CONNECTION_NAME: nom de la connexion créée précédemment ;maxperrun: nombre maximum de factures à traiter ;datestart/dateend: période à exporter si nécessaire ;mode = "mail"pour recevoir les fichiers par email ;mode = "post"pour les envoyer vers un endpoint externe.
Le script fourni utilise les endpoints européens zohoapis.eu. Vérifiez que le domaine correspond bien au data center de votre organisation avant utilisation.
9. Transmettre les fichiers à votre plateforme agréée
Une fois les fichiers Factur-X générés, ils doivent être transmis à votre plateforme.
Deux possibilités principales :
Export manuel
Eventmaker → Zoho → Factur-X → dépôt sur votre plateforme
Export automatisé
Eventmaker → Zoho Books → Factur-X → API de votre plateforme
Le mode post du script Books permet notamment d'envoyer chaque fichier vers un endpoint HTTP externe. Cette intégration nécessite que votre plateforme fournisse une API ou un endpoint compatible.
10. Tester avant la mise en production
Avant d'automatiser le processus sur un grand volume :
créez quelques factures de test ;
vérifiez qu'elles sont bien au statut Open ;
contrôlez les informations clients ;
générez quelques Factur-X ;
vérifiez que votre plateforme les accepte ;
testez ensuite l'automatisation Books sur un petit nombre de factures ;
consultez les logs et les éventuels échecs.
Un échec sur une facture n'interrompt pas nécessairement le traitement des suivantes dans le script fourni.
En résumé
Besoin | Zoho Invoice | Zoho Books |
Générer une facture depuis Eventmaker | ✅ | ✅ |
Exporter un Factur-X | ✅ | ✅ |
Utiliser une autre plateforme que B2Brouter | ✅ | ✅ |
Exporter plusieurs Factur-X automatiquement | Non documenté | ✅ via script Deluge |
Envoyer automatiquement les Factur-X à une API externe | Non documenté | ✅ via adaptation du script |
Pour un faible volume, Zoho Invoice ou Zoho Books peuvent être utilisés avec une autre plateforme agréée.
Pour un volume important nécessitant un export Factur-X automatisé, Zoho Books est actuellement la solution la plus adaptée grâce au script/API fourni par Zoho.
Annexe — Bulk export Factur-X avec Zoho Books
Le script ci-dessous a été fourni pour automatiser l'export Factur-X depuis Zoho Books.
/* Bulk Factur-X export - Zoho Books Schedule Fetches Factur-X files for your invoices and emails them together. Requires a Zoho Books connection with scope ZohoBooks.invoices.READ. Replace the values below. Keep each value on ONE line inside its quotes - a pasted line break causes "is not supported in Deluge". */ org = "YOUR_ORGANIZATION_ID"; mailto = "your.email@yourcompany.com"; /* Invoices to process in this run. */ maxperrun = 50; /* Files per email. Total attachments must stay below 15 MB, or the email is delivered WITHOUT them and no error is raised. Factur-X files are 30-45 KB, so 50 per email is roughly 2 MB and safe. Larger runs split automatically. */ perbatch = 50; /* "mail" attaches the files to an email, "post" sends each to your endpoint. */ mode = "mail"; posturl = "https://your-endpoint.example.com/upload"; posttoken = "YOUR_TOKEN"; /* Optional date range. Plain YYYY-MM-DD. */ datestart = ""; dateend = ""; /* Optional modified-since filter. MUST be full ISO 8601 with a timezone offset, for example "2026-08-01T00:00:00+0200". A plain date matches nothing and the run returns zero invoices without any error. */ modifiedsince = ""; /* Result page. Page size is 200. Use 2, 3 ... for later pages. */ pagenum = 1; /* ---------- 0. Configuration check ---------- */ if(org == "YOUR_ORGANIZATION_ID" || mailto == "your.email@yourcompany.com") { info "Configuration incomplete. Replace org and mailto at the top of the script,"; info "and replace YOUR_CONNECTION_NAME in both invokeurl blocks below."; return; } if(mode == "post") { if(posturl == "https://your-endpoint.example.com/upload") { info "mode is post but posturl is still the placeholder."; return; } } /* ---------- 1. Retrieve the invoice list ---------- */ listurl = "https://www.zohoapis.eu/books/v3/invoices?organization_id=" + org + "&per_page=200&sort_column=date&page=" + pagenum; if(modifiedsince != "") { listurl = listurl + "&last_modified_time=" + modifiedsince; } if(datestart != "") { listurl = listurl + "&date_start=" + datestart; } if(dateend != "") { listurl = listurl + "&date_end=" + dateend; } lr = invokeurl [ url : listurl type : GET connection:"YOUR_CONNECTION_NAME" ]; invlist = lr.get("invoices"); if(invlist == null) { info "Could not retrieve invoices. Response:"; info lr; return; } info "Invoices retrieved: " + invlist.size(); filelist = List(); batchnames = List(); oklist = List(); faillist = List(); count = 0; batchno = 0; /* ---------- 2. Fetch each Factur-X file ---------- */ for each inv in invlist { if(count < maxperrun) { st = inv.get("status"); iid = inv.get("invoice_id"); inum = inv.get("invoice_number"); /* Only issued invoices can produce Factur-X. An invoice still showing "Draft" as its number has no sequential number assigned yet. */ if(st != "draft" && st != "void" && inum != "Draft") { r = invokeurl [ url :"https://www.zohoapis.eu/books/v3/einvoices/" + iid + "?entity_type=invoice&format_type=FacturX&organization_id=" + org type :GET connection:"YOUR_CONNECTION_NAME" detailed :true ]; /* A failed generation still returns HTTP 200 with an error in the body. Check content-type, not the status code. */ hdr = r.get("responseHeader"); ct = hdr.get("content-type"); verdict = "no"; if(ct != null) { if(ct.contains("pdf")) { verdict = "yes"; } } if(verdict == "yes") { if(mode == "post") { out = invokeurl [ url : posturl type : POST files : r.get("responseText") headers : {"Authorization":"Bearer " + posttoken} detailed : true ]; info "Sent " + inum + " - HTTP " + out.get("responseCode"); oklist.add(inum); } else { filelist.add(r.get("responseText")); batchnames.add(inum); oklist.add(inum); info "Fetched " + inum; /* Send as soon as a batch is full, then start a new one. */ if(filelist.size() >= perbatch) { batchno = batchno + 1; body = "<b>Factur-X export</b><br><br>"; body = body + "Organisation: " + org + "<br>"; body = body + "Part " + batchno + "<br>"; body = body + "Files in this email: " + filelist.size() + "<br><br>"; body = body + "<b>Invoices included</b><br>" + batchnames.toString() + "<br>"; sendmail [ from : zoho.adminuserid to : mailto subject : "Factur-X export - part " + batchno + " - " + filelist.size() + " files" message : body attachments : file: filelist ] info "Sent part " + batchno; filelist = List(); batchnames = List(); } } } else { /* One invoice failing does not stop the rest of the batch. */ faillist.add(inum + " :: " + r.get("responseText")); info "Failed " + inum; } count = count + 1; } } } /* ---------- 3. Final email with the summary ---------- */ body = "<b>Factur-X export</b><br><br>"; body = body + "Organisation: " + org + "<br>"; if(datestart != "") { body = body + "Date range: " + datestart + " to " + dateend + "<br>"; } if(modifiedsince != "") { body = body + "Modified since: " + modifiedsince + "<br>"; } body = body + "<br><b>Summary</b><br>"; body = body + "Invoices retrieved: " + invlist.size() + "<br>"; body = body + "Processed this run: " + count + "<br>"; body = body + "Delivered: " + oklist.size() + "<br>"; body = body + "Failed: " + faillist.size() + "<br>"; if(count == maxperrun) { body = body + "<br>The run limit of " + maxperrun + " was reached. More invoices may remain in this range.<br>"; } body = body + "<br><b>Delivered invoices</b><br>" + oklist.toString() + "<br>"; if(faillist.size() > 0) { body = body + "<br><b>Failed invoices and reasons</b><br>" + faillist.toString() + "<br>"; } if(filelist.size() > 0) { body = body + "<br>Files attached to this email: " + filelist.size() + "<br>"; body = body + "<b>Invoices in this email</b><br>" + batchnames.toString() + "<br>"; sendmail [ from : zoho.adminuserid to : mailto subject : "Factur-X export - " + oklist.size() + " delivered, " + faillist.size() + " failed" message : body attachments : file: filelist ] } else { sendmail [ from : zoho.adminuserid to : mailto subject : "Factur-X export - " + oklist.size() + " delivered, " + faillist.size() + " failed" message : body ] } info "Processed: " + count + " Delivered: " + oklist.size() + " Failed: " + faillist.size();

