import {
generateInvoice,
generateInvoiceXml,
signXml,
getP12FromLocalFile,
documentReception,
documentAuthorization
} from 'open-factura';
import * as dotenv from 'dotenv';
dotenv.config();
async function completeInvoiceProcess() {
// 1. Generate invoice
const { invoice, accessKey } = generateInvoice({
infoTributaria: {
ambiente: "1",
tipoEmision: "1",
razonSocial: "My Company",
nombreComercial: "My Store",
ruc: "1234567890001",
codDoc: "01",
estab: "001",
ptoEmi: "001",
secuencial: "000000001",
dirMatriz: "Main Street 123",
},
infoFactura: {
fechaEmision: "15/03/2026",
dirEstablecimiento: "Main Street 123",
obligadoContabilidad: "SI",
tipoIdentificacionComprador: "04",
razonSocialComprador: "Customer Name",
identificacionComprador: "0987654321001",
direccionComprador: "Customer Address",
totalSinImpuestos: "100.00",
totalDescuento: "0.00",
totalConImpuestos: {
totalImpuesto: [{
codigo: "2",
codigoPorcentaje: "2",
baseImponible: "100.00",
tarifa: "12.00",
valor: "12.00",
}],
},
importeTotal: "112.00",
moneda: "DOLAR",
pagos: {
pago: [{ formaPago: "01", total: "112.00" }],
},
},
detalles: {
detalle: [{
codigoPrincipal: "PROD001",
descripcion: "Product Name",
cantidad: "1.000000",
precioUnitario: "100.000000",
descuento: "0.00",
precioTotalSinImpuesto: "100.00",
impuestos: {
impuesto: [{
codigo: "2",
codigoPorcentaje: "2",
tarifa: "12.00",
baseImponible: "100.00",
valor: "12.00",
}],
},
}],
},
});
// 2. Convert to XML
const invoiceXml = generateInvoiceXml(invoice);
// 3. Sign
const p12Certificate = getP12FromLocalFile(process.env.CERTIFICATE_PATH);
const signedXml = await signXml(
p12Certificate,
process.env.CERTIFICATE_PASSWORD,
invoiceXml
);
// 4. Submit to reception
const receptionResult = await documentReception(
signedXml,
process.env.SRI_RECEPTION_URL
);
if (receptionResult.RespuestaRecepcionComprobante.estado !== 'RECIBIDA') {
throw new Error('Reception failed');
}
console.log('✓ Document received');
// 5. Wait for processing
console.log('Waiting for SRI to process...');
await new Promise(resolve => setTimeout(resolve, 3000));
// 6. Request authorization with retry
const authResult = await authorizeWithRetry(accessKey);
if (authResult.success) {
console.log('✓ Document authorized!');
console.log('Authorization Number:', authResult.numeroAutorizacion);
console.log('Authorization Date:', authResult.fechaAutorizacion);
return authResult;
} else {
console.error('✗ Authorization failed');
authResult.messages.forEach(msg => {
console.error(`${msg.identificador}: ${msg.mensaje}`);
});
throw new Error('Authorization failed');
}
}
// Helper function from previous example
async function authorizeWithRetry(
accessKey: string,
maxRetries = 5,
delayMs = 2000
) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
const result = await documentAuthorization(
accessKey,
process.env.SRI_AUTHORIZATION_URL
);
const autorizacion = result.RespuestaAutorizacionComprobante
.autorizaciones.autorizacion[0];
if (autorizacion.estado === 'AUTORIZADO') {
return {
success: true,
numeroAutorizacion: autorizacion.numeroAutorizacion,
fechaAutorizacion: autorizacion.fechaAutorizacion,
comprobante: autorizacion.comprobante
};
}
if (autorizacion.estado === 'NO AUTORIZADO') {
return {
success: false,
messages: autorizacion.mensajes?.mensaje || []
};
}
if (attempt < maxRetries) {
await new Promise(resolve => setTimeout(resolve, delayMs));
}
}
throw new Error('Authorization timeout');
}
completeInvoiceProcess()
.then(result => console.log('Process completed:', result))
.catch(error => console.error('Process failed:', error));