### 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
```