Integrate your own invoice collection¶
Your management system knows how to produce invoices; the module knows how to certify them. Between the two, the exchange happens through files, on an SFTP drop declared on the model: your program deposits its documents there and picks the answers up there. The Minlessika FNE agent is a ready-made implementation of that exchange — nothing forces you to use it, and this guide describes the contract so that you can write your own.
Screen names are given in French
The Minlessika interface is available in French and in English. Each tab or button name is shown here as it appears on a French screen, with its English translation in parentheses.
Prerequisites¶
- A model created, with its two flows — Facture (Invoice) and Avoir (Credit note) — and their mapping
- The
BACKUP.CONFIGUREpermission, to declare the collect of the model - The access to the shared SFTP drop: host, port, user, password
- Four distinct folders on that drop: work, success, error and return
Steps¶
1. Declare the collect of the model¶
Open Paramètres › Modèles (Settings › Models), open your model, then click Collecte (Collect). The Collecte du modèle (Collect of the model) dialog asks for the Canal (Channel) — SFTP —, the access, then the four folders:
| Field | Purpose |
|---|---|
| SFTP dossier de travail (SFTP work folder) | Where your program deposits its documents |
| SFTP dossier succès (SFTP success folder) | Where the module files what it has read |
| SFTP dossier erreur (SFTP error folder) | Where it files what it refuses, with the reason |
| Dossier de retour (Return folder) | Where it writes the verdicts and the certified documents |
Finally tick Activer la collecte (Enable the collect): without that box, nothing is picked up.
Four folders, four paths
Do not point two of these folders at the same place. The module picks up the .xml, .csv and .json files of the work folder: a return folder confused with it would see its verdicts read back as documents to import.
2. Read the flow identifier and the field codes¶
A file is not named to be recognized: it carries, inside, the flow identifier it belongs to. In the Fichiers modèles (Model files) section of the model, download the empty file of the Facture (Invoice) flow, then the one of the Avoir (Credit note) flow, in the format you will produce — CSV, XML or JSON.
That file is your specification: it already carries the flow marker, one element per field named after its code, its type and, where it applies, its required nature. The codes of the fields shipped with each nature also sit in the reference.
3. Produce one file per document¶
A file carries one document, and only one: an invoice, or a credit note. In XML, the ModelImport root carries the flow identifier and a single Invoice — or CreditNote for the credit note flow — whose every line is a Line:
<?xml version="1.0" encoding="UTF-8"?>
<ModelImport model="6f6b1f2e-2f1c-4a52-9e7b-3d2a5c8f1b04">
<Invoice>
<reference>FA-2026-000128</reference>
<issueDate>2026-08-16</issueDate>
<customerName>Société Kouassi</customerName>
<Line>
<lineNo>1</lineNo>
<productName>Sac de ciment 50 kg</productName>
<quantity>40</quantity>
<unitPrice>4500</unitPrice>
</Line>
</Invoice>
</ModelImport>
In JSON, the model key carries the same identifier, the invoice — or creditNote — object carries the document, and its lines array the lines:
{
"model": "6f6b1f2e-2f1c-4a52-9e7b-3d2a5c8f1b04",
"invoice": {
"reference": "FA-2026-000128",
"issueDate": "2026-08-16",
"lines": [{ "lineNo": 1, "quantity": 40 }]
}
}
In CSV, the marker is written on the very first line, before the column header:
#model:6f6b1f2e-2f1c-4a52-9e7b-3d2a5c8f1b04
Write the files in UTF-8 and the dates as yyyy-mm-dd. The expected formats of numbers and booleans hold here as everywhere else.
4. Name each file¶
The name announces the nature of the document and serves as the key of the whole exchange:
| Document | Name |
|---|---|
| Invoice | INV_{id}.xml, INV_{id}.csv or INV_{id}.json |
| Credit note | CRN_{id}.xml, CRN_{id}.csv or CRN_{id}.json |
The prefixes are written in uppercase. {id} is a stable and unique identifier of your system — the key of the invoice in your database, for instance —, with no timestamp and no counter: the same document deposited again must give the same name. That name, extension stripped, is the correlation key that every answer will repeat.
5. Deposit without leaving a file half written¶
The module takes a file only if its size has not moved between two passes. That is a precaution, not a guarantee: write under a temporary name, then rename once the writing is over. The rename is atomic on an SFTP server, and the file then appears whole.
6. Deposit the invoices before their credit notes¶
A credit note quotes the invoice it corrects, and is worth nothing before it. The module handles the invoices first at each pass, but it does not wait for the certification of the invoice to take a credit note deposited at the same time.
The ordering is yours
Deposit the credit note only after the certification verdict of its invoice has arrived in the return folder. A credit note deposited earlier is taken for what it is: a document quoting an invoice not yet certified.
7. Consume the returns¶
Once the document is judged, the module writes in the return folder files named after the one you deposited. An accepted document produces two of them:
| File | Contents |
|---|---|
{name}.json |
The verdict: status at ACCEPTED, reference granted by the FNE, verification url, certification date and number, the reference of the document as it stood in your file |
{name}.pdf |
The certified document |
A refused document produces a single one, {name}.err.json: status at REJECTED, message telling the cause, code of the answer, source of the refusal and date.
Pick these files up at the pace that suits you, and move them away once handled. Key your processing on the file name: the module may write a same verdict again, identical, and your program must be able to read it once more without consequence.
The collect imports, it does not certify
A collected document joins the Imports screen and then follows the usual path: see Submit an import to the FNE. The return is written only once the FNE verdict is known.
8. Handle the refused files¶
A file the module cannot attribute goes to the error folder, together with a {name}.metadata.json note repeating the name of the file and the list of its errors, each with its reason. There land the unreadable file, the one whose extension is neither .xml, .csv nor .json, the one carrying no model marker, the one carrying an unreadable or unknown one, the one whose marker names the flow of another model, and the one not carrying exactly one document.
A well-formed file whose contents are refused — required field left empty, date badly written, field rule violated — follows another path: it joins the success folder, since it was indeed read, and the refusal is read in the detail of the import.
Good practices¶
- One document per file. If your system exports by batch, split before depositing.
- Deterministic names. They are your deduplication key, the module's and yours.
- No renaming afterwards. The deposited name is the one the answers will carry.
- No redeposit of a document already handled. The module refuses a reference already certified, or already sitting in an import: the document is not certified twice, but that refusal is read in the Imports screen and not in the return folder.
- A repair redeposit stays possible. After a
{name}.err.json, the corrected document may be deposited again under the same name and the same reference.
What next?¶
- Submit an import to the FNE, once the documents are collected
- Replay a failed submission
- If you would rather write nothing, the Minlessika FNE agent already holds this contract: it extracts the documents from your database, deposits them and brings the answers back. Ask your Minlessika contact for it, its installation manual comes along.
Changelog¶
- 1.0 (August 16, 2026): document created.