Skip to main content
This guide will walk you through creating a complete electronic invoice, signing it, and submitting it to the SRI.

Prerequisites

Before starting, ensure you have:
  • Open Factura installed in your project
  • A valid .p12 digital certificate from Security Data or Banco Central
  • SRI reception and authorization endpoint URLs
  • Your company’s tax information (RUC, business name, etc.)

Step-by-step guide

1

Import required functions

Start by importing the functions you’ll need from Open Factura:
import {
  generateInvoice,
  generateInvoiceXml,
  signXml,
  getP12FromUrl,
  getP12FromLocalFile,
  documentReception,
  documentAuthorization
} from "open-factura";
2

Create invoice data

Build your invoice data structure with type safety. Here’s a basic example:
const { invoice, accessKey } = generateInvoice({
  infoTributaria: {
    ambiente: "1", // 1 = Testing, 2 = Production
    tipoEmision: "1",
    razonSocial: "Mi Empresa S.A.",
    nombreComercial: "Mi Empresa",
    ruc: "1234567890001",
    codDoc: "01", // 01 = Invoice
    estab: "001",
    ptoEmi: "001",
    secuencial: "000000001",
    dirMatriz: "Av. Principal 123, Quito"
  },
  infoFactura: {
    fechaEmision: "15/01/2024",
    dirEstablecimiento: "Av. Principal 123, Quito",
    obligadoContabilidad: "SI",
    tipoIdentificacionComprador: "05", // 05 = RUC
    razonSocialComprador: "Cliente ABC S.A.",
    identificacionComprador: "0987654321001",
    direccionComprador: "Calle Secundaria 456, Quito",
    totalSinImpuestos: "100.00",
    totalDescuento: "0.00",
    totalConImpuestos: {
      totalImpuesto: [
        {
          codigo: "2", // IVA
          codigoPorcentaje: "2", // 12%
          baseImponible: "100.00",
          tarifa: "12.00",
          valor: "12.00"
        }
      ]
    },
    importeTotal: "112.00",
    moneda: "DOLAR",
    pagos: {
      pago: [
        {
          formaPago: "01", // Cash
          total: "112.00"
        }
      ]
    }
  },
  detalles: {
    detalle: [
      {
        codigoPrincipal: "PROD-001",
        descripcion: "Producto de ejemplo",
        cantidad: "10.000000",
        precioUnitario: "10.000000",
        descuento: "0.00",
        precioTotalSinImpuesto: "100.00",
        impuestos: {
          impuesto: [
            {
              codigo: "2",
              codigoPorcentaje: "2",
              tarifa: "12.00",
              baseImponible: "100.00",
              valor: "12.00"
            }
          ]
        }
      }
    ]
  }
});
The generateInvoice function returns both the invoice object and the auto-generated access key.
3

Generate XML

Convert the invoice to SRI-compliant XML format:
const invoiceXml = generateInvoiceXml(invoice);
4

Load and sign with certificate

Load your .p12 certificate and sign the XML document:
// Load from local file
const signature = getP12FromLocalFile("./certificates/my-cert.p12");

// Or load from URL
// const signature = await getP12FromUrl("https://example.com/cert.p12");

const password = process.env.CERT_PASSWORD || "your-password";

const signedInvoice = await signXml(signature, password, invoiceXml);
Open Factura supports certificates from both Security Data and Banco Central providers.
5

Submit to SRI reception

Send the signed document to the SRI reception endpoint:
const receptionUrl = process.env.SRI_RECEPTION_URL!;

const receptionResult = await documentReception(
  signedInvoice,
  receptionUrl
);

console.log("Reception result:", receptionResult);
6

Get authorization

Request authorization from the SRI using the access key:
const authorizationUrl = process.env.SRI_AUTHORIZATION_URL!;

const authorizationResult = await documentAuthorization(
  accessKey,
  authorizationUrl
);

console.log("Authorization result:", authorizationResult);

Complete example

Here’s a full working example putting it all together:
complete-example.ts
import {
  generateInvoice,
  generateInvoiceXml,
  signXml,
  getP12FromLocalFile,
  documentReception,
  documentAuthorization
} from "open-factura";

async function createAndSubmitInvoice() {
  // Generate invoice
  const { invoice, accessKey } = generateInvoice({
    infoTributaria: {
      ambiente: "1",
      tipoEmision: "1",
      razonSocial: "Mi Empresa S.A.",
      nombreComercial: "Mi Empresa",
      ruc: "1234567890001",
      codDoc: "01",
      estab: "001",
      ptoEmi: "001",
      secuencial: "000000001",
      dirMatriz: "Av. Principal 123, Quito"
    },
    infoFactura: {
      fechaEmision: "15/01/2024",
      dirEstablecimiento: "Av. Principal 123",
      obligadoContabilidad: "SI",
      tipoIdentificacionComprador: "05",
      razonSocialComprador: "Cliente ABC S.A.",
      identificacionComprador: "0987654321001",
      direccionComprador: "Calle Secundaria 456",
      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: "PROD-001",
        descripcion: "Producto de ejemplo",
        cantidad: "10.000000",
        precioUnitario: "10.000000",
        descuento: "0.00",
        precioTotalSinImpuesto: "100.00",
        impuestos: {
          impuesto: [{
            codigo: "2",
            codigoPorcentaje: "2",
            tarifa: "12.00",
            baseImponible: "100.00",
            valor: "12.00"
          }]
        }
      }]
    }
  });

  // Generate XML
  const invoiceXml = generateInvoiceXml(invoice);

  // Sign document
  const signature = getP12FromLocalFile("./cert.p12");
  const signedInvoice = await signXml(
    signature,
    process.env.CERT_PASSWORD!,
    invoiceXml
  );

  // Submit to SRI
  const receptionResult = await documentReception(
    signedInvoice,
    process.env.SRI_RECEPTION_URL!
  );

  // Get authorization
  const authorizationResult = await documentAuthorization(
    accessKey,
    process.env.SRI_AUTHORIZATION_URL!
  );

  return {
    accessKey,
    reception: receptionResult,
    authorization: authorizationResult
  };
}

createAndSubmitInvoice()
  .then(result => console.log("Invoice submitted:", result))
  .catch(error => console.error("Error:", error));

Environment variables

Create a .env file with your configuration:
.env
# Testing environment
SRI_RECEPTION_URL=https://celcer.sri.gob.ec/comprobantes-electronicos-ws/RecepcionComprobantesOffline?wsdl
SRI_AUTHORIZATION_URL=https://celcer.sri.gob.ec/comprobantes-electronicos-ws/AutorizacionComprobantesOffline?wsdl

# Certificate password
CERT_PASSWORD=your-certificate-password
Never commit your .env file or certificate passwords to version control. Use environment variables in production.

Next steps

Complete workflow

See the end-to-end invoice workflow

Type definitions

Explore all available types

Document signing

Learn about digital signatures

SRI integration

Understand SRI endpoints

Build docs developers (and LLMs) love