Submissió d'un fitxer de Flux 10 e-reporting generat per tu
Aquesta guia explica com dipositar al PPF un fitxer de Flux 10 (e-reporting) que ja genera el teu sistema, sense que les factures subjacents passin per la facturació de B2Brouter. B2Brouter valida el fitxer contra l’XSD oficial v3.2, el normalitza per al dipòsit i el transmet a la DGFiP com a Plateforme Agréée, i et retorna els estats del cicle CDV per webhook i per API. És un camí alternatiu al pipeline natiu — on envies dades de factura en JSON i B2Brouter construeix el F10 — i tots dos comparteixen la mateixa canonada de sortida cap al PPF.
Per a qui és aquesta guia
Section titled “Per a qui és aquesta guia”Per a integradors i editors de programari que ja produeixen el seu propi <Report> F10
i només necessiten un canal acreditat per dipositar-lo. Si el que vols és que B2Brouter
generi el F10 a partir de les teves factures, no facis servir aquesta guia: consulta la
secció d’e-Reporting (Flux 10) de la guia DGFiP.
Prerequisits
Section titled “Prerequisits”- Un compte francès a B2Brouter amb el Tax Report Setting
dgfiphabilitat. Consulta els passos 1 i 2 de la guia DGFiP. X-B2B-API-Version: 2026-03-02o posterior.- Els permisos d’API per als endpoints de ledgers activats al teu pla. Si reps un
403, obre un tiquet de suport per fer-los habilitar. - El fitxer F10 vàlid contra el paquet XSD oficial v3.2.
Els exemples fan servir
https://api-staging.b2brouter.net. Per a producció, substitueix-ho perhttps://api.b2brouter.net.
Dipositar el fitxer
Section titled “Dipositar el fitxer”POST /accounts/{ACCOUNT_ID}/ledgers/importEl cos de la petició és el XML cru, amb Content-Type: application/octet-stream
(qualsevol altre content type es rebutja: així evitem que Rails intenti interpretar el
cos com a paràmetres).
curl --request POST \ --url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/ledgers/import \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: 2026-03-02' \ --header 'Content-Type: application/octet-stream' \ --header 'Idempotency-Key: f10-2026-01-transactions-001' \ --data-binary @flux10-transactions.xmlResposta — 201 Created:
{ "ledger": { "id": 68916, "type": "dgfip", "state": "new" }}L’id del ledger és l’identificador amb què seguiràs tot el cicle de vida. Guarda’l.
Estructura mínima del fitxer
Section titled “Estructura mínima del fitxer”El fitxer és un <Report> sense namespace. B2Brouter en llegeix tres coses per decidir
si el pot dipositar: el <Issuer>, el sub-flux declarat i la validesa XSD.
<?xml version="1.0" encoding="UTF-8"?><Report xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <ReportDocument> <Id>el-teu-identificador</Id> <Name>Déclaration Transactions Janvier 2026</Name> <IssueDateTime> <DateTimeString>202602110400</DateTimeString> </IssueDateTime> <TypeCode>IN</TypeCode> <Sender> <!-- El substituïm per la identitat de PA de B2Brouter en dipositar --> <Id schemeId="0238">0426</Id> <Name>PDP426</Name> <RoleCode>WK</RoleCode> <URIUniversalCommunication> <URIID>contact@exemple.fr</URIID> </URIUniversalCommunication> </Sender> <Issuer> <!-- Ha de coincidir amb el SIREN de l'empresa del compte destí --> <Id schemeId="0002">832987911</Id> <Name>METACORTEX</Name> <RoleCode>SE</RoleCode> <URIUniversalCommunication> <URIID>contact@metacortex.fr</URIID> </URIUniversalCommunication> </Issuer> </ReportDocument> <TransactionsReport> <!-- … o <PaymentsReport>, però no tots dos alhora --> </TransactionsReport></Report>Un sol sub-flux per dipòsit. El PPF transmet transaccions i encaixos per separat
(spec v3.2 §3.7.7): un <Report> ha de portar <TransactionsReport> o
<PaymentsReport>. El sub-flux declarat determina el mode del ledger. Un report amb tots
dos, o sense cap dels dos, es rebutja.
Validacions, en ordre
Section titled “Validacions, en ordre”| # | Comprovació | Si falla |
|---|---|---|
| 1 | Content-Type: application/octet-stream | 406 — Content-Type must be application/octet-stream |
| 2 | Mida del cos ≤ 100 Mo (límit IRR_TAILLE del PPF, v3.2 §3.4.2) | 422 — The payload exceeds the PPF file limit of 100 Mo |
| 3 | Validació XSD contra el paquet oficial v3.2 | 422 amb el detall dels errors de l’esquema |
| 4 | Versió d’API ≥ 2026-03-02 | 422 — DGFiP F10 import requires API version 2026-03-02 or later |
| 5 | El compte té el setting dgfip habilitat | 422 — The account has no enabled DGFiP e-reporting configuration |
| 6 | El SIREN de <Issuer><Id> coincideix amb l’empresa del compte | 422 — The <Issuer> SIREN (…) does not match the account's company |
| 7 | Un únic sub-flux (transactions o payments) | 422 — The report carries both transactions and payments; split it into two deposits o The report carries neither transactions nor payments |
L’element arrel decideix l’autoritat: un <Report> sense namespace s’interpreta com a F10
de la DGFiP; qualsevol altra arrel segueix tractant-se com un ledger Verifactu, de manera
que l’import de Verifactu continua funcionant a totes les versions d’API.
Idempotència
Section titled “Idempotència”Envia una capçalera Idempotency-Key amb cada dipòsit. Si no n’envies, fem servir el
SHA256 del payload, de manera que reenviar un fitxer idèntic també és idempotent.
| Escenari | Resposta |
|---|---|
| Clau nova | 201 amb el ledger creat |
| Mateixa clau, mateix payload | 200 amb el ledger que ja existia — no es crea cap duplicat |
| Mateixa clau, payload diferent | 409 — Idempotency-Key already used with a different payload |
La clau és única per compte. Les claus de més de 64 caràcters o amb caràcters no ASCII s’emmagatzemen com a resum SHA256; el comportament és el mateix.
Normalització del dipòsit
Section titled “Normalització del dipòsit”Abans de transmetre, B2Brouter reescriu dos nodes del teu fitxer:
<ReportDocument><Id>passa a ser l’id del ledger. És la clau amb què el PPF correlaciona els CDV de retorn; si mantinguéssim un valor triat pel client, un dipòsit podria reclamar les respostes d’un ledger d’un altre compte.<ReportDocument><Sender>passa a ser la identitat de Plateforme Agréée de B2Brouter (matricule ambschemeId="0238",RoleCodeWK), perquè el dipositant al PPF som nosaltres. L’AIFE ha confirmat per escrit que aquesta normalització de dipòsit és acceptable.
La resta del fitxer no es toca, i la tramesa original es conserva tal com l’hem rebuda com a adjunt d’auditoria del ledger.
Enviament al PPF
Section titled “Enviament al PPF”El ledger importat queda en estat new i el cron d’enviament el recull en la primera
execució passada la mitjanit del dia del dipòsit: en la pràctica, es diposita al PPF
l’endemà. El transport és un dipòsit SFTP al PPF (tar.gz amb l’envelope F10).
El règim de TVA no intervé en els fitxers importats: la periodització per règim és una funció del pipeline natiu. Aquí la cadència és la del dipòsit, i el període declarat és el que tu escrius al fitxer.
Seguir el cicle de vida
Section titled “Seguir el cicle de vida”Estats del ledger
Section titled “Estats del ledger”| Estat | CDV del PPF | Significat |
|---|---|---|
new | — | Importat i validat, pendent de dipòsit |
sent | — | Dipositat al PPF |
acknowledged | 500 — Reçue | El PPF ha rebut el fitxer |
deposited | — | Dipòsit acceptat pel PPF |
registered | 300 | ✅ Terminal — declaració registrada per la DGFiP |
refused | 301 | ❌ Terminal — rebutjada; error_code i error_description porten el motiu |
error | — | Error de transmissió; error_description porta el detall |
Webhooks (recomanat)
Section titled “Webhooks (recomanat)”Subscriu-te a l’esdeveniment ledger.state_change per rebre cada transició sense
pollejar. Es dispara en entrar a sent, error, acknowledged, deposited, registered
i refused.
{ "web_hook": { "url": "https://example.com/hooks", "events": ["ledger.state_change"] }}El cos que reps porta l’id del compte i el ledger sencer:
{ "account_id": 42, "object": { "object": "ledger", "id": 68916, "state": "registered", "mode": null, "error_code": null, "error_description": null, "document_type_code": "xml.ledger.dgfip.transactions", "sent_at": "2026-07-25T02:04:11.000Z", "created_at": "2026-07-24T10:12:03.000Z" }}Si dos CDV arriben molt seguits, l’estat ja superat no es lliura: sempre reps l’estat vigent, no necessàriament un lliurament per transició. Consulta el ledger si necessites confirmar l’estat actual. Per a la verificació de la signatura del webhook, consulta la guia de webhooks.
Consultar l’estat
Section titled “Consultar l’estat”curl --request GET \ --url https://api-staging.b2brouter.net/ledgers/{LEDGER_ID} \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: 2026-03-02'{ "ledger": { "id": 68916, "type": "dgfip", "state": "refused", "error_code": "303", "error_description": null, "created_at": "2026-07-24T10:12:03.000Z", "sent_at": "2026-07-25T02:04:11.000Z" }}Descarregar el fitxer dipositat
Section titled “Descarregar el fitxer dipositat”GET /ledgers/{LEDGER_ID}/downloadRetorna el XML normalitzat que hem dipositat (amb l’<Id> i el <Sender> reescrits),
disponible des del moment de l’import. És el document que cal conservar com a prova del que
s’ha declarat.
Descarregar la resposta del PPF
Section titled “Descarregar la resposta del PPF”GET /ledgers/{LEDGER_ID}/download_responseRetorna el CDV rebut del PPF. Mentre no n’hi ha cap, retorna 404.
En mode Sandbox,
downloadidownload_responseretornen 503: no hi ha dipòsit real ni respostes del PPF.