Verifactu
La loi antifraude (Loi 11/2021) impose aux entreprises de garantir que leurs systèmes de facturation et de comptabilité respectent des normes techniques strictes afin d’éviter toute manipulation des données. Le Décret royal 1007/2023 précise davantage les exigences techniques applicables aux systèmes de facturation numérique, en insistant sur la nécessité de formats de facture standardisés facilement accessibles pour l’administration fiscale.
Ces réglementations obligent les entreprises à adopter des systèmes capables de générer, stocker et transmettre de manière sécurisée les factures et les déclarations fiscales. L’API REST de B2Brouter est une solution technique qui permet à votre entreprise d’être facilement 100 % conforme en déléguant les complexités à B2Brouter et en vous laissant vous concentrer sur la logique métier de votre système.
Qu’est-ce que Verifactu ?
Section titled “Qu’est-ce que Verifactu ?”Verifactu est un système de conformité conçu pour simplifier le respect des exigences de facturation prévues par la loi antifraude. Il garantit que toutes les factures générées par les entreprises sont transmises de manière sécurisée à l’administration fiscale afin que leur intégrité et leur authenticité puissent être vérifiées à la fois par l’administration fiscale et par le client. L’administration fiscale espagnole est l’AEAT (“Agencia Estatal de Administración Tributaria”).
Verifactu implique la soumission immédiate, en temps réel, des données de facture à l’AEAT dès l’émission de la facture. Cela garantit qu’aucune modification ne peut être effectuée après son émission, assurant ainsi sa sécurité. De plus, la facture contient un code QR qui permet au destinataire de vérifier sa conformité fiscale via la plateforme de l’AEAT.
En pratique, Verifactu exige :
- La création d’un fichier XML de déclaration fiscale.
- Le calcul d’une empreinte numérique pour chaque déclaration fiscale. Cela inclut une chaîne de hachage pour créer une piste inviolable.
- L’assemblage d’un “Libro de Registro” ou registre pouvant contenir une ou plusieurs déclarations fiscales.
- La soumission authentifiée du “Libro de Registro” à l’AEAT à l’aide d’un certificat électronique qualifié.
- Le respect des limitations de fréquence définies par l’AEAT (max. 1 appel par minute, sauf en cas de soumission de plus de 1 000 factures).
- La génération d’un code QR de vérification de facture, à inclure dans la facture émise.
- Le traitement des réponses de l’AEAT pour chaque déclaration fiscale.
Avec B2Brouter, vous pouvez abstraire une grande partie de la complexité de ce processus et respecter la loi antifraude en effectuant seulement quelques appels REST à l’API. Vous n’aurez pas besoin de votre propre certificat électronique qualifié, car B2Brouter est un Collaborateur Social en Gestion Fiscale. Vous avez seulement besoin d’une clé API B2Brouter valide.
Environnements de test : utilisez le sandbox pour les premiers tests API et la validation des payloads. Le sandbox simule les soumissions Verifactu afin que vous puissiez tester le cycle de vie des factures sans atteindre l’AEAT. Pour des tests complets de bout en bout avec l’endpoint de test de l’AEAT, utilisez l’environnement staging (
api-staging.b2brouter.net).
Configuration et utilisation de l’API B2Brouter
Section titled “Configuration et utilisation de l’API B2Brouter”La première étape consiste à configurer Verifactu pour chacune des entreprises pour lesquelles vous souhaitez soumettre des déclarations fiscales. Vous pouvez consulter le guide Tax Report Settings pour une description complète du processus. L’appel pour configurer un compte est le suivant :
Exemple de requête
curl --request GET \ --url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/tax_report_settings \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'Content-Type: application/json' \ --data '{ "tax_report_setting": { "code": "Verifactu", "start_date": "2025-04-06", "auto_generate": true, "auto_send": true, "reason_vat_exempt": "E1", "special_regime_key": "01", "reason_no_subject": "N1", "credit_note_code": "R1" } }'API Invoice
Section titled “API Invoice”Si vous utilisez B2Brouter à la fois pour émettre les factures et les déclarer à l’administration fiscale, une fois votre compte correctement configuré, vous pouvez opérer comme vous le faites normalement pour l’émission de factures.
Les factures émises contiendront le code QR obligatoire, et la déclaration fiscale Verifactu sera envoyée automatiquement à l’AEAT. Voici un exemple d’appel pour créer et émettre une facture :
Exemple de requête :
curl --request POST \ --url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/invoices \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'content-type: application/json' \ --data '{ "send_after_import": true, "invoice": { "date": "2025-04-15", "due_date": "2025-05-15", "number": 48, "payment_method": 1, "contact": { "name": "contact.name", "address": "contact.address", "city": "contact.city", "province": "contact.province", "postalcode": "28938", "country": "es", "email": "john.doe@example.com", "language": "es", "currency": "EUR", "terms": "15", "payment_method": 1, "tin_scheme": 9920, "tin_value": "ESA28388510" }, "invoice_lines_attributes": [ { "quantity": 10.0, "description": "line.description", "price": 11.0, "unit": 9, "taxes_attributes": [ { "name": "IVA", "percent": 21.0, "category": "S" } ] } ] } }'Dans la réponse du POST REST pour la création d’une facture, si send_after_import est défini sur true, vous trouverez une section tax_report_ids dans laquelle se trouve l’ID de la déclaration fiscale associée à la facture.
Vous pouvez accéder à la déclaration fiscale complète, y compris le code QR, son identifiant, son état et tous les autres champs, en appelant le endpoint get tax report avec l’ID de déclaration fiscale fourni dans la réponse de l’appel de création de facture.
L’état de la déclaration fiscale sera toujours processing dans la réponse du POST. Vous devez vérifier le cycle de vie de la déclaration fiscale. Deux options sont possibles :
- La méthode recommandée consiste à utiliser le webhook tax report. États finaux : registered, error et registered_with_errors
- Effectuer un polling de l’état de la déclaration fiscale avec l’endpoint get tax report jusqu’à ce que le champ state soit registered, error ou registered_with_errors.
API Tax Report
Section titled “API Tax Report”Si vous n’utilisez pas B2Brouter pour émettre les factures, si vous avez besoin de plus de contrôle sur le processus de génération et de traitement des déclarations fiscales, ou si vous prévoyez un volume élevé de déclarations, vous pouvez utiliser la nouvelle API Tax Report.
Cette API est conçue pour un contrôle maximal par l’utilisateur et une haute disponibilité. Vous pouvez soumettre des déclarations fiscales soit sous forme de payload JSON, soit sous forme de XML Verifactu valide.
La structure du format JSON des déclarations fiscales B2Brouter s’appuie sur PEPPOL Continuous Transaction Control (CTC). L’API Tax Report de B2Brouter est une API universelle, pas seulement orientée Verifactu, mais conçue pour gérer le reporting fiscal à l’échelle mondiale.
Il est important de noter que les déclarations fiscales comportent des ventilations fiscales (“desglose” en espagnol), qui sont la somme des lignes de la facture d’origine ayant la même taxe. Il est de la responsabilité de votre système d’agréger les lignes de facture par type et catégorie de taxe et de fournir les ventilations fiscales nécessaires. Le modèle TaxReport n’effectue aucun calcul.
Créer une déclaration fiscale
Section titled “Créer une déclaration fiscale”Pour créer une déclaration fiscale, vous devez appeler l’endpoint create tax report. Une déclaration fiscale minimale et valide :
Exemple de requête :
curl --request POST \ --url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/tax_reports \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'Content-Type: application/json' \ --data '{ "tax_report": { "type": "Verifactu", "invoice_date": "2025-04-03", "invoice_number": "11", "description": "Lorem ipsum...", "customer_party_tax_id": "B12345678", "customer_party_country": "es", "customer_party_name": "Ejemplo S.L.", "tax_inclusive_amount": 121.0, "tax_amount": 21.0, "invoice_type_code": "F1", "currency": "EUR", "tax_breakdowns": [ { "name": "IVA", "category": "S", "non_exemption_code": "S1", "percent": 21.0, "taxable_base": 100.0, "tax_amount": 21.0, "special_regime_key": "01" } ] } }'La réponse de ce POST contiendra déjà le champ qr avec le code QR (encodé en base64) que vous devez inclure sur la facture destinée à votre client. Le contenu de ce code QR est une URL qui permettra à votre client de vérifier que l’AEAT a reçu et traité la déclaration fiscale issue de sa facture.
Importer une déclaration fiscale à partir d’un fichier XML Verifactu
Section titled “Importer une déclaration fiscale à partir d’un fichier XML Verifactu”Si votre système est capable de générer des fichiers XML Verifactu (un RegistroAlta ou un RegistroAnulacion de l’espace de noms SuministroInformacion), vous pouvez les importer directement via l’API en utilisant l’endpoint d’import.
Si la création de la déclaration fiscale réussit, la réponse contiendra déjà le code QR et l’identifiant de la déclaration fiscale. Notez que B2Brouter effectuera le processus d’enchaînement indépendamment de toute information d’enchaînement présente dans le XML importé.
Vérifier l’état d’une déclaration fiscale
Section titled “Vérifier l’état d’une déclaration fiscale”Le champ state de la déclaration fiscale sera toujours processing après une création réussie. Vérifiez le cycle de vie via :
- Le webhook tax report. États finaux : registered, error, annulled et registered_with_errors
- Le polling de l’endpoint get tax report jusqu’à ce que le champ state soit l’un des suivants : registered, error, annulled ou registered_with_errors.
Obtenir la représentation XML de la déclaration fiscale
Section titled “Obtenir la représentation XML de la déclaration fiscale”Utilisez le endpoint download tax report. B2Brouter inclut également un champ nommé xml_base64 dans la réponse du GET. Notez que le XML ne peut être généré qu’après l’enchaînement de la déclaration fiscale.
Vérification des erreurs
Section titled “Vérification des erreurs”B2Brouter a mis en œuvre un ensemble exhaustif de validations des déclarations fiscales Verifactu basées sur les spécifications publiées par l’AEAT. En cas d’erreur de validation, la déclaration fiscale ne sera pas créée. Vous recevrez une réponse 422: Unprocessable Entity avec toutes les erreurs au format JSON.
Annuler une déclaration fiscale
Section titled “Annuler une déclaration fiscale”Pour annuler une déclaration fiscale (“anulación” en espagnol), utilisez le verbe DELETE en appelant l’endpoint d’annulation.
Corriger une déclaration fiscale
Section titled “Corriger une déclaration fiscale”Pour corriger une déclaration fiscale (“subsanación” en espagnol), utilisez les verbes PATCH ou PUT en appelant l’endpoint de correction.
API Ledgers
Section titled “API Ledgers”Les déclarations fiscales Verifactu ne sont pas envoyées individuellement à l’AEAT ; elles sont regroupées dans un “Libro de Registro” (Ledger dans la terminologie B2Brouter), qui contient jusqu’à 1000 déclarations fiscales. Chaque déclaration fiscale possède un champ ledger_id qui identifie l’ID interne du ledger. Avec cet ID, vous pouvez :
- Récupérer la représentation XML du Ledger en appelant l’endpoint download ledger.
- Récupérer la réponse XML de l’AEAT au Ledger envoyé par B2Brouter en appelant l’endpoint download response.
Équivalence entre les champs internes de déclaration fiscale B2Brouter et les nœuds XML Verifactu
Section titled “Équivalence entre les champs internes de déclaration fiscale B2Brouter et les nœuds XML Verifactu”| Champ B2Brouter (basé sur PEPPOL CTC) | Nœud XML Verifactu |
|---|---|
| invoice_date | IDFactura > FechaExpedicionFactura |
| invoice_number | IDFactura > NumSerieFactura |
| invoice_series_code | IDFactura > NumSerieFactura |
| supplier_party_name | NombreRazonEmisor |
| external_reference | RefExterna |
| correction | Subsanacion |
| annullation | Anulación |
| previously_refused | RechazoPrevio |
| invoice_type_code | TipoFactura |
| amend_type | TipoFactura |
| amended_number | FacturasRectificadas > IDFacturaRectificada > NumSerieFactura |
| amended_series_code | FacturasRectificadas > IDFacturaRectificada > NumSerieFactura |
| amended_date | FacturasRectificadas > IDFacturaRectificada > FechaExpedicionFactura |
| amended_tax_exclusive | ImporteRectificacion > BaseRectificada |
| amended_tax_amount | ImporteRectificacion > CuotaRectificada |
| tax_point_date | FechaOperacion |
| description | DescripcionOperacion |
| simplified_art7273 | FacturaSimplificadaArt7273 |
| ticket | FacturaSinIdentifDestinatarioArt61d |
| macrodata | Macrodato |
| issued_by_third_party_or_receiver | EmitidaPorTerceroODestinatario |
| third_party_name | Tercero > NombreRazon |
| third_party_tax_id | Tercero > NIF |
| customer_party_name | Destinatarios > IDDestinatario > NombreRazon |
| customer_party_tax_id | Destinatarios > IDDestinatario > NIF or IDOtro > IDType |
| customer_party_country | Destinatarios > IDDestinatario > IDOtro > CodigoPais |
| customer_party_tax_scheme | Destinatarios > IDDestinatario > IDOtro > IDType |
| tax_breakdowns[].name | Desglose > DetalleDesglose > Impuesto |
| tax_breakdowns[].special_regime_key | Desglose > DetalleDesglose > ClaveRegimen |
| tax_breakdowns[].non_exemption_code | Desglose > DetalleDesglose > CalificacionOperacion |
| tax_breakdowns[].exemption_code | Desglose > DetalleDesglose > OperacionExenta |
| tax_breakdowns[].percent | Desglose > DetalleDesglose > TipoImpositivo |
| tax_breakdowns[].taxable_base | Desglose > DetalleDesglose > BaseImponibleOimporteNoSujeto |
| tax_breakdowns[].taxable_base_at_cost | Desglose > DetalleDesglose > BaseImponibleACoste |
| tax_breakdowns[].tax_amount | Desglose > DetalleDesglose > CuotaRepercutida |
| tax_amount | CuotaTotal |
| tax_inclusive_amount | ImporteTotal |
| previous_id | Encadenamiento > RegistroAnterior > NumSerieFactura |
Fichiers XSD
Section titled “Fichiers XSD”| Fichier XSD | Description |
|---|---|
| SuministroLR.xsd | Opérations d’enregistrement et d’annulation des systèmes Verifactu et non Verifactu |
| RespuestaSuministro.xsd | Réponse aux opérations des systèmes Verifactu et non Verifactu |
| ConsultaLR.xsd | Opération de consultation des registres de facturation Verifactu |
| RespuestaConsultaLR.xsd | Réponse à l’opération de consultation des registres de facturation Verifactu |
| SuministroInformacion.xsd | Définition des types communs |
Description des codes pour des champs spécifiques
Section titled “Description des codes pour des champs spécifiques”Codes de type de facture
Section titled “Codes de type de facture”Paramètre : invoice_type_code
| Code | Description |
|---|---|
| F1 | Facture (art. 6, 7.2 et 7.3 du RD 1619/2012) |
| F2 | Facture simplifiée et factures sans identification du destinataire (art. 6.1.d) RD 1619/2012 |
| F3 | Facture émise en remplacement de factures simplifiées facturées et déclarées |
| R1 | Facture rectificative (Erreur fondée en droit et art. 80 Un, Deux et Six LIVA) |
| R2 | Facture rectificative (art. 80.3) |
| R3 | Facture rectificative (art. 80.4) |
| R4 | Facture rectificative (autres cas) |
| R5 | Facture rectificative sur factures simplifiées |
Codes de clé de régime spécial
Section titled “Codes de clé de régime spécial”Paramètre : special_regime_key
| Code | Description |
|---|---|
| 01 | Opération de régime général. |
| 02 | Exportation. |
| 03 | Opérations relevant du régime spécial des biens d’occasion, objets d’art, antiquités et objets de collection. |
| 04 | Régime spécial de l’or d’investissement. |
| 05 | Régime spécial des agences de voyages. |
| 06 | Régime spécial de groupe d’entités en TVA (niveau avancé) |
| 07 | Régime spécial du critère de caisse. |
| 08 | Opérations soumises à l’IPSI / IGIC. |
| 17 | Opération relevant de l’un des régimes prévus au chapitre XI du titre IX (OSS et IOSS) |
| 18 | Recargo de equivalencia. |
| 19 | Opérations d’activités incluses dans le Régime spécial d’agriculture, élevage et pêche (REAGYP) |
| 20 | Régime simplifié |
Codes de non-exonération
Section titled “Codes de non-exonération”Paramètre : non_exemption_code
| Code | Description |
|---|---|
| S1 | Opération soumise et non exonérée, sans inversion du redevable. |
| S2 | Opération soumise et non exonérée, avec inversion du redevable. |
Codes de non-assujettissement
Section titled “Codes de non-assujettissement”Paramètre : no_subject_code
| Code | Description |
|---|---|
| N1 | Opération non soumise, article 7, 14, autres. |
| N2 | Opération non soumise en raison des règles de localisation. |
Codes d’exonération
Section titled “Codes d’exonération”Paramètre : exemption_code
| Code | Description |
|---|---|
| E1 | Exonérée par l’article 20 |
| E2 | Exonérée par l’article 21 |
| E3 | Exonérée par l’article 22 |
| E4 | Exonérée par les articles 23 et 24 |
| E5 | Exonérée par l’article 25 |
| E6 | Exonérée pour d’autres motifs |
Type d’identifiant client
Section titled “Type d’identifiant client”Paramètre : customer_party_tax_scheme
| Code | Description |
|---|---|
| 02 | N° de TVA intracommunautaire (NIF-IVA) |
| 03 | Passeport |
| 04 | Pièce d’identité officielle émise par le pays de résidence |
| 05 | Certificat de résidence |
| 06 | Autre document justificatif |
| 07 | Non enregistré |