### Pagination Flow Example Source: https://github.com/guerreron47/verifactu-js/blob/main/docs/specs/web-services-sections/06_query_service.md Illustrates the step-by-step process of handling pagination for retrieving all invoice records. It shows the sequence of queries and responses, starting without a pagination key and ending when all records are fetched. ```text Query 1 (no ClavePaginacion) ↓ Response: 10,000 records + IndicadorPaginacion="S" + ClavePaginacion ↓ Query 2 (with ClavePaginacion from Response 1) ↓ Response: 10,000 records + IndicadorPaginacion="S" + ClavePaginacion ↓ Query 3 (with ClavePaginacion from Response 2) ↓ Response: 3,421 records + IndicadorPaginacion="N" ↓ END (all records retrieved) ``` -------------------------------- ### XML Example - Cancellation due to Rejection Source: https://github.com/guerreron47/verifactu-js/blob/main/docs/specs/web-services-sections/05_operational_flows.md Provides an example of an XML request for cancelling a billing record when a prior rejection occurred. ```APIDOC ## POST /api/billing/cancel/rejection ### Description This endpoint is used to cancel a billing record that was previously rejected by AEAT. It requires specific XML payload detailing the cancellation. ### Method POST ### Endpoint /api/billing/cancel/rejection ### Parameters #### Request Body - **xml_payload** (string) - Required - The XML payload containing the cancellation details, including the `RechazoPrevio` flag set to 'S'. ### Request Example ```xml XXXXX AAAA 1.0 AAAA 12345 13-09-2024 S AAAA 44 13-09-2024 HuellaRegistroAnterior SSSS NNNN NombreSistemaInformatico 77 1.0.03 383 N S S 2024-09-13T19:20:30+01:00 01 Huella ``` ### Response #### Success Response (200) - **message** (string) - Confirmation message indicating successful cancellation. #### Response Example ```json { "message": "Billing record cancelled successfully." } ``` ``` -------------------------------- ### XML Pagination Key Example Source: https://github.com/guerreron47/verifactu-js/blob/main/docs/specs/web-services-sections/06_query_service.md An example of the XML structure for the pagination key. This block is crucial for subsequent queries when more than 10,000 records are returned, containing the details of the last record from the previous response. ```xml XXXXXXXXX 10000 28-11-2024 ``` -------------------------------- ### Verifactu Error Response Example (JSON) Source: https://github.com/guerreron47/verifactu-js/blob/main/docs/specs/qr-code-spec.md Demonstrates the structure of a single error response from the Verifactu system. It includes status, message, visibility, crashlytics flag, and error code. ```json { "status": "KO", "mensaje": "El importe tiene un formato incorrecto", "visible": "S", "crashlytics": "N", "codigo_error": "2005" } ``` -------------------------------- ### Query by Issuer with Counterparty Filter Source: https://github.com/guerreron47/verifactu-js/blob/main/docs/specs/web-services-sections/06_query_service.md This example demonstrates how to query invoices issued by a specific entity, filtering by a particular customer/recipient NIF. ```APIDOC ## POST /ConsultaFactuSistemaFacturacion ### Description Queries invoices issued by a specific entity, with an optional filter for a particular counterparty's NIF. ### Method POST ### Endpoint /ConsultaFactuSistemaFacturacion ### Parameters #### Request Body - **con:ConsultaFactuSistemaFacturacion** (xml) - Required - The main XML structure for the query. - **con:Cabecera** (xml) - Required - Header information for the query. - **sum:IDVersion** (string) - Required - The version of the ID. - **sum:ObligadoEmision** (xml) - Required - Information about the issuing entity. - **sum:NombreRazon** (string) - Required - The name or legal reason of the issuer. - **sum:NIF** (string) - Required - The NIF of the issuer. - **con:FiltroConsulta** (xml) - Optional - Filters to apply to the invoice query. - **con:PeriodoImputacion** (xml) - Optional - Specifies the accounting period. - **sum:Ejercicio** (integer) - Required - The year of the accounting period. - **sum:Periodo** (integer) - Required - The month of the accounting period. - **con:Contraparte** (xml) - Optional - Filters by counterparty information. - **sum:NombreRazon** (string) - Required - The name or legal reason of the counterparty. - **sum:NIF** (string) - Required - The NIF of the counterparty. ### Request Example ```xml 1.0 EMPRESAXXXX XXXXXXXXX 2024 11 EMPRESAYYYY A84532509 ``` ### Response #### Success Response (200) - **env:Envelope** (xml) - The SOAP envelope containing the query results. - **env:Body** (xml) - The body of the SOAP response. - **tikLRRC:RespuestaConsultaFactuSistemaFacturacion** (xml) - The main structure for the query response. - **tikLRRC:RegistroRespuestaConsultaFactuSistemaFacturacion** (xml) - Contains details of each queried invoice. #### Response Example ```xml ``` ``` -------------------------------- ### XML: Submit Batch of 3 Records to Verifactu Source: https://github.com/guerreron47/verifactu-js/blob/main/docs/specs/web-services-sections/05_operational_flows.md This XML example demonstrates a batch submission containing three records to the Verifactu system. It includes the header information and details for each transaction, such as invoice data, system information, and chaining for cancellations. This format is used for reporting billing information. ```xml XXXXX AAAA 1.0 AAAA 12345 13-02-2024 XXXXX F1 Descripc YYYY BBBB 01 S1 4 10 0.4 01 S1 21 100 21 21.4 131.4 AAAA 44 13-02-2024 HuellaRegistroAnterior44 SSSS NNNN NombreSistemaInformatico 77 1.0.03 383 N S S 2024-02-13T19:20:30+01:00 01 Huella 1.0 AAAA 12311 13-02-2024 AAAA 12345 13-02-2024 HuellaRegistroAnterior12345 SSSS NNNN ``` -------------------------------- ### Paginated Query by Recipient Source: https://github.com/guerreron47/verifactu-js/blob/main/docs/specs/web-services-sections/06_query_service.md This example demonstrates how a recipient can query invoices from their suppliers with pagination, using specific invoice details for navigation. ```APIDOC ## POST /ConsultaFactuSistemaFacturacion ### Description Allows a recipient to query invoices from their suppliers, using pagination to retrieve results incrementally. ### Method POST ### Endpoint /ConsultaFactuSistemaFacturacion ### Parameters #### Request Body - **con:ConsultaFactuSistemaFacturacion** (xml) - Required - The main XML structure for the query. - **con:Cabecera** (xml) - Required - Header information for the query. - **sum:IDVersion** (string) - Required - The version of the ID. - **sum:Destinatario** (xml) - Required - Information about the recipient entity. - **sum:NombreRazon** (string) - Required - The name or legal reason of the recipient. - **sum:NIF** (string) - Required - The NIF of the recipient. - **sum:MostrarSistemaInformatico** (string) - Optional - Set to 'N' or omit for this query type. - **con:FiltroConsulta** (xml) - Optional - Filters to apply to the invoice query. - **con:PeriodoImputacion** (xml) - Optional - Specifies the accounting period. - **sum:Ejercicio** (integer) - Required - The year of the accounting period. - **sum:Periodo** (integer) - Required - The month of the accounting period. - **con:ClavePaginacion** (xml) - Optional - Used for paginating results. - **sum:IDEmisorFactura** (string) - Required - The ID of the invoice issuer. - **sum:NumSerieFactura** (string) - Required - The serial number of the invoice. - **sum:FechaExpedicionFactura** (string) - Required - The expedition date of the invoice (DD-MM-YYYY). ### Request Example ```xml 1.0 EMPRESAXXXX XXXXXXXXX 2024 11 XXXXXXXXX 10000 28-11-2024 ``` ### Response #### Success Response (200) - **env:Envelope** (xml) - The SOAP envelope containing the query results. - **env:Body** (xml) - The body of the SOAP response. - **tikLRRC:RespuestaConsultaFactuSistemaFacturacion** (xml) - The main structure for the query response. - **tikLRRC:RegistroRespuestaConsultaFactuSistemaFacturacion** (xml) - Contains details of each queried invoice. #### Response Example ```xml ``` ``` -------------------------------- ### XML Example: Encadenamiento for Chaining Records Source: https://github.com/guerreron47/verifactu-js/blob/main/docs/specs/xml-structure.md Demonstrates the XML structure for the 'Encadenamiento' element, used to link records sequentially. It shows how to indicate the first record in a chain and how to reference a previous record by providing its identifying details and hash. ```xml S B12345678 F-2024-001 01-01-2024 abc123... ``` -------------------------------- ### Verifactu Multiple Errors Response Example (JSON) Source: https://github.com/guerreron47/verifactu-js/blob/main/docs/specs/qr-code-spec.md Illustrates how multiple errors are handled in a Verifactu system response. Errors are concatenated using a period (.) as a separator within the 'mensaje' field. ```json { "status": "KO", "mensaje": "No se ha remitido el parametro: fecha...No se ha remitido el parametro: importe", "visible": "S", "crashlytics": "N", "codigo_error": "1003.1004" } ``` -------------------------------- ### XML Example: Cancellation Due to Rejection Source: https://github.com/guerreron47/verifactu-js/blob/main/docs/specs/web-services-sections/05_operational_flows.md This XML structure demonstrates a cancellation request where a previous record was rejected. It includes fields for the original invoice details, the reason for cancellation (RechazoPrevio set to 'S'), and system information. This is used when an invoice needs to be cancelled after an initial rejection. ```xml XXXXX AAAA 1.0 AAAA 12345 13-09-2024 S AAAA 44 13-09-2024 HuellaRegistroAnterior SSSS NNNN NombreSistemaInformatico 77 1.0.03 383 N S S 2024-09-13T19:20:30+01:00 01 Huella ``` -------------------------------- ### Complete Workflow: Validate, Hash, and Generate QR (TypeScript) Source: https://context7.com/guerreron47/verifactu-js/llms.txt Demonstrates the end-to-end process for handling an invoice record using Verifactu-JS. It covers validating the record's data integrity, calculating its SHA-256 hash for blockchain inclusion, and generating a QR code URL for verification. This example requires the '@verifactu/core' package and utilizes functions like `validateRecordAlta`, `calculateHashAlta`, and `generateQRUrlFromRecord`. ```typescript import { validateRecordAlta, calculateHashAlta, generateQRUrlFromRecord, type RegistroFacturacionAltaType, type ChainContext } from '@verifactu/core' // Step 1: Create invoice record const record: RegistroFacturacionAltaType = { IDVersion: '1.0', IDFactura: { IDEmisorFactura: '89890001K', NumSerieFactura: '12345678/G33', FechaExpedicionFactura: '01-01-2024' }, NombreRazonEmisor: 'Test Company S.L.', TipoFactura: 'F1', DescripcionOperacion: 'Sale of goods', Destinatarios: { IDDestinatario: [{ NIF: 'B12345678', NombreRazon: 'Customer Company S.L.' }] }, Desglose: { DetalleDesglose: [{ Impuesto: '01', ClaveRegimen: '01', CalificacionOperacion: 'S1', TipoImpositivo: '21.00', BaseImponibleOimporteNoSujeto: '100.00', CuotaRepercutida: '21.00' }] }, CuotaTotal: '12.35', ImporteTotal: '123.45', Encadenamiento: { PrimerRegistro: 'S' }, SistemaInformatico: { NombreRazon: 'Developer Company S.L.', NIF: '12345678A', NombreSistemaInformatico: 'TestSystem', IdSistemaInformatico: '01', Version: '1.0.0', NumeroInstalacion: 'INSTALL001', TipoUsoPosibleSoloVerifactu: 'S', TipoUsoPosibleMultiOT: 'N', IndicadorMultiplesOT: 'N' }, FechaHoraHusoGenRegistro: '2024-01-01T19:20:30+01:00', TipoHuella: '01', Huella: '' } // Step 2: Validate the record const validation = validateRecordAlta(record) if (!validation.valid) { console.error('Validation failed:', validation.errors) throw new Error('Invalid record') } console.log('✓ Validation passed') // Step 3: Calculate hash (first record in chain) const chainContext: ChainContext = { isFirstRecord: true, previousHash: '' } const hashResult = calculateHashAlta(record, chainContext) console.log('✓ Hash calculated:', hashResult.hash) // Update record with calculated hash record.Huella = hashResult.hash // Step 4: Generate QR verification URL const qrResult = generateQRUrlFromRecord(record, { environment: 'production', systemType: 'verifiable' }) if (qrResult.success) { console.log('✓ QR URL generated:', qrResult.url) } else { console.error('QR generation failed:', qrResult.error) } // Step 5: Store hash for next record // In your application, persist hashResult.hash to use as previousHash // for the next invoice in the chain // For subsequent invoices: const nextRecord: RegistroFacturacionAltaType = { /* ... next invoice ... */ } const nextChain: ChainContext = { isFirstRecord: false, previousHash: hashResult.hash // Use previous hash } const nextHash = calculateHashAlta(nextRecord, nextChain) console.log('✓ Next record hash:', nextHash.hash) ``` -------------------------------- ### Verifactu Invoice Verification JSON Response Example Source: https://github.com/guerreron47/verifactu-js/blob/main/docs/specs/qr-code-spec.md This JSON structure represents the response when verifying an invoice using the 'formato=json' parameter. It indicates the status, a message, and detailed invoice information or error codes if the invoice is not found or not verifiable. The 'respuesta.resultado' field provides a specific code for the verification outcome. ```json { "status": "OK", "mensaje": "Factura encontrada", "visible": "N", "crashlytics": "N", "respuesta": { "resultado": "00", "nif": "89890001K", "numserie": "12345678-G33", "fecha": "01-09-2024", "importe": "241.40" } } ``` ```json { "status": "OK", "mensaje": "Factura no encontrada", "visible": "N", "crashlytics": "N", "respuesta": { "resultado": "01", "nif": "89890001K", "numserie": "12345678-G33", "fecha": "01-09-2024", "importe": "241.50" } } ``` ```json { "status": "OK", "mensaje": "Factura no verificable", "visible": "N", "crashlytics": "N", "respuesta": { "resultado": "02", "nif": "89890001K", "numserie": "12345678-G33", "fecha": "01-09-2024", "importe": "241.40" } } ``` -------------------------------- ### Query by Issuer with Date Range Filter Source: https://github.com/guerreron47/verifactu-js/blob/main/docs/specs/web-services-sections/06_query_service.md This example shows how to query invoices issued by a specific entity within a defined expedition date range. ```APIDOC ## POST /ConsultaFactuSistemaFacturacion ### Description Queries invoices issued by a specific entity within a specified date range for invoice expedition. ### Method POST ### Endpoint /ConsultaFactuSistemaFacturacion ### Parameters #### Request Body - **con:ConsultaFactuSistemaFacturacion** (xml) - Required - The main XML structure for the query. - **con:Cabecera** (xml) - Required - Header information for the query. - **sum:IDVersion** (string) - Required - The version of the ID. - **sum:ObligadoEmision** (xml) - Required - Information about the issuing entity. - **sum:NombreRazon** (string) - Required - The name or legal reason of the issuer. - **sum:NIF** (string) - Required - The NIF of the issuer. - **con:FiltroConsulta** (xml) - Optional - Filters to apply to the invoice query. - **con:PeriodoImputacion** (xml) - Optional - Specifies the accounting period. - **sum:Ejercicio** (integer) - Required - The year of the accounting period. - **sum:Periodo** (integer) - Required - The month of the accounting period. - **con:FechaExpedicionFactura** (xml) - Optional - Filters by the invoice expedition date. - **sum:RangoFechaExpedicion** (xml) - Required - The range for the expedition date. - **sum:Desde** (string) - Required - The start date of the range (DD-MM-YYYY). - **sum:Hasta** (string) - Required - The end date of the range (DD-MM-YYYY). ### Request Example ```xml 1.0 EMPRESAXXXX XXXXXXXXX 2024 11 02-11-2024 13-11-2024 ``` ### Response #### Success Response (200) - **env:Envelope** (xml) - The SOAP envelope containing the query results. - **env:Body** (xml) - The body of the SOAP response. - **tikLRRC:RespuestaConsultaFactuSistemaFacturacion** (xml) - The main structure for the query response. - **tikLRRC:RegistroRespuestaConsultaFactuSistemaFacturacion** (xml) - Contains details of each queried invoice. #### Response Example ```xml ``` ``` -------------------------------- ### Generate Verifactu Registration Reference String (Java) Source: https://github.com/guerreron47/verifactu-js/blob/main/docs/specs/hash-algorithm.md This Java function constructs the reference string for a Verifactu registration (e.g., cancellation). It concatenates various fields, formatted using the getValorCampo helper method, to create the string that will be hashed. It requires several parameters representing invoice and registration details. ```java public class GeneradorHuella { // ... getHashVerifactu method ... public static String getReferenciaRegistroAlta( String nifEmisor, String numFacturaSerie, String fechaExpedicion, String tipoFactura, String cuotaTotal, String importeTotal, String huellaAnterior, String fechaHoraHusoRegistro) { StringBuilder sb = new StringBuilder(); return sb .append(getValorCampo("IDEmisorFactura", nifEmisor, true)) .append(getValorCampo("NumSerieFactura", numFacturaSerie, true)) .append(getValorCampo("FechaExpedicionFactura", fechaExpedicion, true)) .append(getValorCampo("TipoFactura", tipoFactura, true)) .append(getValorCampo("CuotaTotal", cuotaTotal, true)) .append(getValorCampo("ImporteTotal", importeTotal, true)) .append(getValorCampo("Huella", huellaAnterior, true)) .append(getValorCampo("FechaHoraHusoGenRegistro", fechaHoraHusoRegistro, false)) .toString(); } // ... getValorCampo method ... } ``` -------------------------------- ### Verifactu-JS Package Dependencies Source: https://github.com/guerreron47/verifactu-js/blob/main/docs/00-Inbox/ARCHITECTURAL_REVIEW.md Illustrates the hierarchical dependencies between the core, xml, and client packages in the Verifactu-JS monorepo. This structure allows for progressive installation and clear separation of concerns. ```plaintext @verifactu/client └── depends on @verifactu/xml └── depends on @verifactu/core ``` -------------------------------- ### Implementation Guidelines for `@verifactu/client` Source: https://github.com/guerreron47/verifactu-js/blob/main/docs/specs/web-services-sections/01_protocol_constraints.md Provides specific implementation guidelines for the `@verifactu/client` library, including required features and error recovery strategies. ```APIDOC ## Implementation Guidelines for `@verifactu/client` ### Required Features 1. **SOAP 1.1 Client**: Document/literal style, HTTPS, UTF-8 encoding. 2. **Batch Management**: Max 1,000 records per submission; automatic splitting of larger batches. 3. **Synchronous Response Handling**: Wait for and parse response XML, extract CSV, statuses, and error codes. 4. **Fault Processing**: Distinguish `soapenv:Server` (retry) and `soapenv:Client` (fix message) faults. Parse `faultstring` for details. 5. **Error Categorization**: Classify errors (admissible/non-admissible) and handle global/record states (`Correcto`, `ParcialmenteCorrecto`, `Incorrecto`, `AceptadoConErrores`). 6. **Certificate Authentication**: Support qualified electronic certificates; secure loading. 7. **Response Parsing**: Extract CSV, parse individual record results, and capture rejection reasons. ### Error Recovery Strategy ```typescript // Pseudocode example async function submitWithRetry(message: XMLMessage): Promise { try { const response = await soapClient.send(message) return parseResponse(response) } catch (error) { if (isSoapFault(error)) { if (error.faultcode === 'soapenv:Server') { // Server error - wait and retry await wait(TiempoEsperaEnvio) // See retry timing field return submitWithRetry(message) } else if (error.faultcode === 'soapenv:Client') { // Client error - fix message before retry throw new ClientError(error.faultstring) } } // Transmission error - retry await wait(TiempoEsperaEnvio) return submitWithRetry(message) } } ``` ``` -------------------------------- ### SOAP Fault Structure Example Source: https://github.com/guerreron47/verifactu-js/blob/main/docs/specs/web-services-sections/01_protocol_constraints.md This snippet demonstrates the standard structure for SOAP Fault messages, used to communicate XML processing incidents. It includes the fault code and a descriptive string. ```xml soapenv:Server Error description ``` -------------------------------- ### TypeScript Unit Test for Hash Calculation Source: https://github.com/guerreron47/verifactu-js/blob/main/docs/00-Inbox/ARCHITECTURAL_REVIEW.md Contains a unit test for the `calculateHash` function, specifically verifying its output against an official AEAT example for the first 'RegistroAlta'. This ensures the hashing mechanism aligns with the expected cryptographic standards. ```typescript describe('calculateHash', () => { it('should match AEAT example for first RegistroAlta', () => { const result = calculateHash(AEAT_EXAMPLE_1) expect(result.hash).toBe('3C464DAF61ACB827C65FDA19F352A4E3BDC2C640E9E9FC4CC058073F38F12F60') }) }) ``` -------------------------------- ### TypeScript Implementation Notes for Verifactu Source: https://github.com/guerreron47/verifactu-js/blob/main/docs/specs/hash-algorithm.md Notes for implementing Verifactu functionalities in TypeScript, specifically regarding hash generation and data handling. It emphasizes using Node.js crypto module, UTF-8 encoding, uppercase hexadecimal output, and proper handling of null/undefined values and whitespace. ```plaintext 1. Use Node.js `crypto` module for SHA-256 2. Convert string to UTF-8 Buffer before hashing 3. Output as uppercase hexadecimal 4. Implement separate functions for each record type 5. Handle null/undefined values as empty strings 6. Always trim whitespace from field values ```