npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ramiidv/arca-mtxca

v0.1.0

Published

TypeScript SDK para el web service WSMTXCA de ARCA (ex AFIP) - Facturacion electronica con detalle de articulos

Readme

@ramiidv/arca-mtxca

SDK de TypeScript para el web service WSMTXCA de ARCA (ex AFIP). Facturacion electronica con detalle de articulos (item-level detail: codigos de barras, cantidades, precios unitarios, descripciones por linea).

Caracteristicas

  • Zero dependencias SOAP: construye los envelopes SOAP manualmente
  • Zero dependencias HTTP: usa fetch nativo (Node 18+)
  • Firma CMS/PKCS#7 con node-forge (via arca-common)
  • ESM only
  • TypeScript estricto con tipos completos
  • Cache automatico de tokens WSAA
  • Reintentos con backoff exponencial
  • Sistema de eventos para monitoreo

Instalacion

npm install @ramiidv/arca-mtxca

WSMTXCA vs WSFEv1

| Caracteristica | WSFEv1 (arca-facturacion) | WSMTXCA (arca-mtxca) | |---|---|---| | Detalle de items | No | Si (codigo, descripcion, cantidad, precio unitario por linea) | | Protocolo | SOAP (.NET) | SOAP (Java) | | Formato fechas | YYYYMMDD | YYYY-MM-DD | | IVA por item | No (subtotales globales) | Si (codigoCondicionIVA + importeIVA por item) | | Tipos cbte | A, B, C, E, M, FCE | A, B, M | | Uso tipico | Facturas sin detalle de productos | Facturas con detalle de productos (ej: retail, e-commerce) |

Inicio rapido

import { readFileSync } from 'fs';
import { ArcaMtxca, CbteTipo, CodigoCondicionIVA } from '@ramiidv/arca-mtxca';

const mtxca = new ArcaMtxca({
  cert: readFileSync('./cert.pem', 'utf-8'),
  key: readFileSync('./key.pem', 'utf-8'),
  cuit: 20123456789,
  production: false, // false = homologacion
});

// Autorizar factura B con detalle de articulos
const result = await mtxca.autorizar({
  ptoVta: 1,
  cbteTipo: CbteTipo.FACTURA_B,
  invoice: {
    concepto: 1, // Productos
    docTipo: 99, // Consumidor Final
    docNro: 0,
    cbteFch: '2026-03-31',
    importeTotal: 121,
    importeGravado: 100,
    importeNoGravado: 0,
    importeExento: 0,
    subtotalesIVA: [
      { codigo: CodigoCondicionIVA.IVA_21, baseImponible: 100, importe: 21 },
    ],
    items: [
      {
        codigo: '7790001000012',
        descripcion: 'Producto de ejemplo',
        cantidad: 2,
        unidadMedida: 7, // unidades
        precioUnitario: 50,
        importeItem: 100,
        codigoCondicionIVA: CodigoCondicionIVA.IVA_21,
        importeIVA: 21,
      },
    ],
  },
});

if (result.resultado === 'A') {
  console.log('CAE:', result.cae);
  console.log('Vencimiento:', result.caeFchVto);
  console.log('Cbte Nro:', result.cbteNro);
}

Configuracion

interface ArcaMtxcaConfig {
  /** Certificado X.509 en formato PEM */
  cert: string;
  /** Clave privada RSA en formato PEM */
  key: string;
  /** CUIT del contribuyente (sin guiones) */
  cuit: number;
  /** Usar endpoints de produccion (default: false) */
  production?: boolean;
  /** Timeout en ms (default: 30000) */
  timeout?: number;
  /** Cantidad de reintentos en errores 5xx/red (default: 1) */
  retries?: number;
  /** Delay base en ms para backoff exponencial (default: 1000) */
  retryDelayMs?: number;
  /** Callback de eventos para monitoreo */
  onEvent?: (event: ArcaEvent) => void;
}

API

Metodos principales

autorizar(request: AutorizarRequest): Promise<MtxcaInvoiceResult>

Autoriza un comprobante con detalle de articulos. Retorna CAE si fue aprobado.

const result = await mtxca.autorizar({
  ptoVta: 1,
  cbteTipo: CbteTipo.FACTURA_A,
  invoice: {
    concepto: 1,
    docTipo: 80, // CUIT
    docNro: 30123456789,
    cbteFch: '2026-03-31',
    importeTotal: 242,
    importeGravado: 200,
    subtotalesIVA: [
      { codigo: CodigoCondicionIVA.IVA_21, baseImponible: 200, importe: 42 },
    ],
    items: [
      {
        codigo: '001',
        descripcion: 'Servicio de consultoria',
        cantidad: 1,
        unidadMedida: 7,
        precioUnitario: 200,
        importeItem: 200,
        codigoCondicionIVA: CodigoCondicionIVA.IVA_21,
        importeIVA: 42,
      },
    ],
  },
});

ultimoComprobante(ptoVta, cbteTipo): Promise<number>

Ultimo numero de comprobante autorizado.

const ultimo = await mtxca.ultimoComprobante(1, CbteTipo.FACTURA_B);

siguienteComprobante(ptoVta, cbteTipo): Promise<number>

Siguiente numero de comprobante (ultimo + 1).

const siguiente = await mtxca.siguienteComprobante(1, CbteTipo.FACTURA_B);

consultarComprobante(cbteTipo, ptoVta, cbteNro): Promise<MtxcaComprobante>

Consulta un comprobante previamente autorizado, incluyendo el detalle de items.

const comprobante = await mtxca.consultarComprobante(CbteTipo.FACTURA_B, 1, 150);
console.log(comprobante.items); // Detalle de articulos

status(): Promise<ServerStatus>

Health check del servicio. No requiere autenticacion.

const estado = await mtxca.status();
console.log(estado.appserver); // "OK"

Consulta de parametros

const tiposCbte = await mtxca.getTiposComprobante();
const tiposDoc = await mtxca.getTiposDocumento();
const alicuotas = await mtxca.getAlicuotasIVA();
const condiciones = await mtxca.getCondicionesIVA();
const monedas = await mtxca.getMonedas();
const unidades = await mtxca.getUnidadesMedida();
const ptosVenta = await mtxca.getPuntosVenta();
const ptosVentaCAE = await mtxca.getPuntosVentaCAE();
const ptosVentaCAEA = await mtxca.getPuntosVentaCAEA();
const cotizacion = await mtxca.getCotizacionMoneda('DOL');

Acceso a clientes de bajo nivel

Para casos avanzados, se pueden usar los clientes individuales directamente:

const mtxca = new ArcaMtxca({ /* ... */ });

// Obtener ticket de acceso manualmente
const ticket = await mtxca.wsaa.getAccessTicket('wsmtxca');

const auth = {
  Token: ticket.token,
  Sign: ticket.sign,
  Cuit: 20123456789,
};

// Llamar directamente al servicio
const result = await mtxca.client.autorizarComprobante(auth, request);

Tipos principales

MtxcaItem

interface MtxcaItem {
  codigo?: string;         // Codigo/barcode del producto
  descripcion: string;     // Descripcion del producto/servicio
  cantidad: number;        // Cantidad
  unidadMedida: number;    // Codigo unidad de medida
  precioUnitario: number;  // Precio unitario
  importeItem: number;     // Importe total del item
  codigoCondicionIVA: number; // Condicion de IVA del item
  importeIVA: number;      // Importe de IVA del item
  importeBonificacion?: number; // Descuento
}

MtxcaInvoiceResult

interface MtxcaInvoiceResult {
  resultado: string;     // "A" = Aprobado, "R" = Rechazado
  cae?: string;          // CAE otorgado
  caeFchVto?: string;    // Vencimiento del CAE (YYYY-MM-DD)
  cbteNro: number;       // Numero de comprobante
  observaciones: MtxcaObservacion[];
  errores: MtxcaObservacion[];
}

MtxcaComprobante

interface MtxcaComprobante {
  codigoTipoComprobante: number;
  numeroPuntoVenta: number;
  numeroComprobante: number;
  fechaEmision: string;
  codigoTipoDocumento: number;
  numeroDocumento: number;
  importeTotal: number;
  importeNoGravado: number;
  importeGravado: number;
  importeExento: number;
  importeOtrosTributos: number;
  importeSubtotal: number;
  codigoMoneda: string;
  cotizacionMoneda: number;
  resultado: string;
  codigoAutorizacion?: string;
  fechaVencimiento?: string;
  observaciones: MtxcaObservacion[];
  items: MtxcaItem[];
}

Manejo de errores

El SDK usa la jerarquia de errores de @ramiidv/arca-common:

Error
  └── ArcaError (base)
        ├── ArcaAuthError (errores de WSAA)
        ├── ArcaServiceError (errores de negocio)
        └── ArcaSoapError (errores HTTP/transporte)
import { ArcaAuthError, ArcaServiceError, ArcaSoapError } from '@ramiidv/arca-mtxca';

try {
  await mtxca.autorizar(request);
} catch (error) {
  if (error instanceof ArcaAuthError) {
    // Certificado vencido, servicio no autorizado, WSAA caido
    console.error('Error de autenticacion:', error.message);
  } else if (error instanceof ArcaServiceError) {
    // Errores de negocio (comprobante rechazado, etc.)
    for (const detalle of error.errors) {
      console.error(`[${detalle.code}] ${detalle.msg}`);
    }
  } else if (error instanceof ArcaSoapError) {
    // Errores HTTP/red
    console.error('Error HTTP:', error.statusCode, error.message);
  }
}

Ademas, las respuestas de autorizar() pueden tener resultado === 'R' con observaciones/errores sin lanzar excepcion. Siempre verificar result.resultado:

const result = await mtxca.autorizar(request);
if (result.resultado !== 'A') {
  console.error('Rechazado:', result.errores);
  console.warn('Observaciones:', result.observaciones);
}

Eventos

const mtxca = new ArcaMtxca({
  // ...
  onEvent: (evento) => {
    switch (evento.type) {
      case 'auth:login':
        console.log(`Login para ${evento.service}`);
        break;
      case 'auth:cache-hit':
        console.log(`Token cacheado para ${evento.service}`);
        break;
      case 'request:start':
        console.log(`Inicio ${evento.method}`);
        break;
      case 'request:end':
        console.log(`Fin ${evento.method} (${evento.durationMs}ms)`);
        break;
      case 'request:retry':
        console.log(`Reintento #${evento.attempt}`);
        break;
      case 'request:error':
        console.error(`Error: ${evento.error}`);
        break;
    }
  },
});

Enums utiles

import { CbteTipo, Concepto, CodigoCondicionIVA, Moneda } from '@ramiidv/arca-mtxca';

// Tipos de comprobante
CbteTipo.FACTURA_A     // 1
CbteTipo.NOTA_DEBITO_A // 2
CbteTipo.NOTA_CREDITO_A // 3
CbteTipo.FACTURA_B     // 6
CbteTipo.NOTA_DEBITO_B // 7
CbteTipo.NOTA_CREDITO_B // 8

// Concepto
Concepto.PRODUCTOS     // 1
Concepto.SERVICIOS     // 2
Concepto.PRODUCTOS_Y_SERVICIOS // 3

// Condicion IVA del item
CodigoCondicionIVA.NO_GRAVADO // 1
CodigoCondicionIVA.EXENTO     // 2
CodigoCondicionIVA.IVA_0      // 3
CodigoCondicionIVA.IVA_10_5   // 4
CodigoCondicionIVA.IVA_21     // 5
CodigoCondicionIVA.IVA_27     // 6
CodigoCondicionIVA.GRAVADO    // 7
CodigoCondicionIVA.IVA_5      // 8
CodigoCondicionIVA.IVA_2_5    // 9

// Monedas
Moneda.PESOS   // "PES"
Moneda.DOLARES // "DOL"
Moneda.EUROS   // "060"

Requisitos

  • Node.js >= 18 (soporte nativo de fetch)
  • Certificado digital emitido por ARCA/AFIP
  • Autorizacion para el servicio wsmtxca

Licencia

MIT