@ramiidv/arca-mtxca
v0.1.0
Published
TypeScript SDK para el web service WSMTXCA de ARCA (ex AFIP) - Facturacion electronica con detalle de articulos
Maintainers
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
fetchnativo (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-mtxcaWSMTXCA 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 articulosstatus(): 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
