@ramiidv/arca-mtxca 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,386 +1,239 @@
1
1
  # @ramiidv/arca-mtxca
2
2
 
3
- 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).
3
+ SDK de TypeScript para el web service **WSMTXCA** de ARCA (ex AFIP): factura electrónica con detalle de ítems (código MTX/GTIN, cantidad, precio unitario e IVA por línea), con CAE y con CAEA.
4
4
 
5
- ## Caracteristicas
5
+ - Tipos fieles al WSDL/XSD de WSMTXCA y elementos en el orden de la secuencia (Axis2 valida el orden).
6
+ - Redondeo según el XSD: 2 decimales en importes, 6 en cantidad, precio unitario, bonificación y cotización.
7
+ - Validación local de las reglas excluyentes del manual (presencia de campos por unidad de medida, fórmulas por ítem, subtotales de IVA por alícuota, totales).
8
+ - Las emisiones nunca se reintentan y los errores con resultado desconocido se marcan como `uncertain`.
9
+ - Los errores de negocio de ARCA (`arrayErrores`) se lanzan como `ArcaServiceError` en las consultas.
10
+ - Autenticación WSAA automática (via `@ramiidv/arca-common`), con `ticketStorage` persistente opcional.
11
+ - ESM, Node 18+, `fetch` nativo.
6
12
 
7
- - Zero dependencias SOAP: construye los envelopes SOAP manualmente
8
- - Zero dependencias HTTP: usa `fetch` nativo (Node 18+)
9
- - Firma CMS/PKCS#7 con node-forge (via arca-common)
10
- - ESM only
11
- - TypeScript estricto con tipos completos
12
- - Cache automatico de tokens WSAA
13
- - Reintentos con backoff exponencial
14
- - Sistema de eventos para monitoreo
15
-
16
- ## Instalacion
13
+ ## Instalación
17
14
 
18
15
  ```bash
19
16
  npm install @ramiidv/arca-mtxca
20
17
  ```
21
18
 
22
- ## WSMTXCA vs WSFEv1
23
-
24
- | Caracteristica | WSFEv1 (`arca-facturacion`) | WSMTXCA (`arca-mtxca`) |
25
- |---|---|---|
26
- | Detalle de items | No | Si (codigo, descripcion, cantidad, precio unitario por linea) |
27
- | Protocolo | SOAP (.NET) | SOAP (Java) |
28
- | Formato fechas | YYYYMMDD | YYYY-MM-DD |
29
- | IVA por item | No (subtotales globales) | Si (codigoCondicionIVA + importeIVA por item) |
30
- | Tipos cbte | A, B, C, E, M, FCE | A, B, M |
31
- | Uso tipico | Facturas sin detalle de productos | Facturas con detalle de productos (ej: retail, e-commerce) |
32
-
33
- ## Inicio rapido
19
+ ## Inicio rápido
34
20
 
35
21
  ```typescript
36
- import { readFileSync } from 'fs';
37
- import { ArcaMtxca, CbteTipo, CodigoCondicionIVA } from '@ramiidv/arca-mtxca';
22
+ import { readFileSync } from 'node:fs';
23
+ import { ArcaMtxca, CbteTipo, Concepto, CodigoCondicionIVA, Moneda } from '@ramiidv/arca-mtxca';
38
24
 
39
25
  const mtxca = new ArcaMtxca({
40
26
  cert: readFileSync('./cert.pem', 'utf-8'),
41
27
  key: readFileSync('./key.pem', 'utf-8'),
42
- cuit: 20123456789,
43
- production: false, // false = homologacion
28
+ cuit: '20-12345678-6',
29
+ production: false, // homologación
44
30
  });
45
31
 
46
- // Autorizar factura B con detalle de articulos
47
- const result = await mtxca.autorizar({
48
- ptoVta: 1,
49
- cbteTipo: CbteTipo.FACTURA_B,
50
- invoice: {
51
- concepto: 1, // Productos
52
- docTipo: 99, // Consumidor Final
53
- docNro: 0,
54
- cbteFch: '2026-03-31',
55
- importeTotal: 121,
56
- importeGravado: 100,
57
- importeNoGravado: 0,
58
- importeExento: 0,
59
- subtotalesIVA: [
60
- { codigo: CodigoCondicionIVA.IVA_21, baseImponible: 100, importe: 21 },
61
- ],
62
- items: [
63
- {
64
- codigo: '7790001000012',
65
- descripcion: 'Producto de ejemplo',
66
- cantidad: 2,
67
- unidadMedida: 7, // unidades
68
- precioUnitario: 50,
69
- importeItem: 100,
70
- codigoCondicionIVA: CodigoCondicionIVA.IVA_21,
71
- importeIVA: 21,
72
- },
73
- ],
74
- },
32
+ // Factura A: 1 producto a $100 + IVA 21%
33
+ const res = await mtxca.autorizar({
34
+ codigoTipoComprobante: CbteTipo.FACTURA_A,
35
+ numeroPuntoVenta: 4000,
36
+ // numeroComprobante: omitido => último autorizado + 1
37
+ fechaEmision: new Date(),
38
+ codigoTipoDocumento: 80,
39
+ numeroDocumento: '30-00000000-7',
40
+ condicionIVAReceptor: 1, // RG 5616: ver getCondicionesIVAReceptor()
41
+ importeGravado: 100,
42
+ importeNoGravado: 0,
43
+ importeExento: 0,
44
+ importeSubtotal: 100,
45
+ importeTotal: 121,
46
+ codigoMoneda: Moneda.PESOS,
47
+ cotizacionMoneda: 1,
48
+ codigoConcepto: Concepto.PRODUCTOS,
49
+ items: [{
50
+ unidadesMtx: 1,
51
+ codigoMtx: '7790001000012',
52
+ codigo: 'P0001',
53
+ descripcion: 'Producto de ejemplo',
54
+ cantidad: 1,
55
+ codigoUnidadMedida: 7,
56
+ precioUnitario: 100, // clase A: sin IVA
57
+ codigoCondicionIVA: CodigoCondicionIVA.IVA_21,
58
+ importeIVA: 21,
59
+ importeItem: 121, // con IVA incluido
60
+ }],
61
+ subtotalesIVA: [{ codigo: CodigoCondicionIVA.IVA_21, importe: 21 }],
75
62
  });
76
63
 
77
- if (result.resultado === 'A') {
78
- console.log('CAE:', result.cae);
79
- console.log('Vencimiento:', result.caeFchVto);
80
- console.log('Cbte Nro:', result.cbteNro);
64
+ if (res.resultado === 'R') {
65
+ console.error('Rechazado', res.errores);
66
+ } else {
67
+ // 'A' aprobado, 'O' aprobado con observaciones
68
+ console.log(res.comprobante.numeroComprobante, res.comprobante.cae, res.comprobante.fechaVencimientoCAE);
69
+ if (res.observaciones.length) console.warn(res.observaciones);
81
70
  }
82
71
  ```
83
72
 
84
- ## Configuracion
73
+ ## Configuración
85
74
 
86
- ```typescript
87
- interface ArcaMtxcaConfig {
88
- /** Certificado X.509 en formato PEM */
89
- cert: string;
90
- /** Clave privada RSA en formato PEM */
91
- key: string;
92
- /** CUIT del contribuyente (sin guiones) */
93
- cuit: number;
94
- /** Usar endpoints de produccion (default: false) */
95
- production?: boolean;
96
- /** Timeout en ms (default: 30000) */
97
- timeout?: number;
98
- /** Cantidad de reintentos en errores 5xx/red (default: 1) */
99
- retries?: number;
100
- /** Delay base en ms para backoff exponencial (default: 1000) */
101
- retryDelayMs?: number;
102
- /** Callback de eventos para monitoreo */
103
- onEvent?: (event: ArcaEvent) => void;
104
- }
105
- ```
75
+ `ArcaMtxcaConfig` extiende `ArcaBaseConfig` de `@ramiidv/arca-common`:
106
76
 
107
- ## API
77
+ | Opción | Descripción |
78
+ | --- | --- |
79
+ | `cert`, `key` | Certificado y clave privada PEM. |
80
+ | `cuit` | CUIT representada (número o string, con o sin guiones). Se valida el dígito verificador. |
81
+ | `production` | `false` (default) = homologación. |
82
+ | `endpoint` | URL de WSMTXCA. Si se indica, ignora `production`. |
83
+ | `wsaaEndpoint` | URL de WSAA. Si se indica, ignora `production` para el login. |
84
+ | `timeout`, `retries`, `retryDelayMs` | Transporte. `retries` solo aplica a consultas. |
85
+ | `ticketStorage` | Storage persistente de tickets WSAA (recomendado en producción). |
86
+ | `tokenTTLMinutes`, `clockOffsetMs`, `autoClockSkew`, `loginErrorCooldownMs` | Opciones de WSAA. |
87
+ | `fetch`, `legacyTls` | `fetch` propio (proxy, tests) y transporte TLS legacy. |
88
+ | `onEvent` | Callback de eventos (`auth:*`, `request:*`). |
108
89
 
109
- ### Metodos principales
90
+ Endpoints (manual WSMTXCA):
110
91
 
111
- #### `autorizar(request: AutorizarRequest): Promise<MtxcaInvoiceResult>`
92
+ | Entorno | URL |
93
+ | --- | --- |
94
+ | Homologación | `https://fwshomo.afip.gov.ar/wsmtxca/services/MTXCAService` |
95
+ | Producción | `https://serviciosjava.afip.gob.ar/wsmtxca/services/MTXCAService` |
112
96
 
113
- Autoriza un comprobante con detalle de articulos. Retorna CAE si fue aprobado.
97
+ Todos los métodos aceptan un último parámetro `opts?: CallOptions` con `signal` para cancelar.
114
98
 
115
- ```typescript
116
- const result = await mtxca.autorizar({
117
- ptoVta: 1,
118
- cbteTipo: CbteTipo.FACTURA_A,
119
- invoice: {
120
- concepto: 1,
121
- docTipo: 80, // CUIT
122
- docNro: 30123456789,
123
- cbteFch: '2026-03-31',
124
- importeTotal: 242,
125
- importeGravado: 200,
126
- subtotalesIVA: [
127
- { codigo: CodigoCondicionIVA.IVA_21, baseImponible: 200, importe: 42 },
128
- ],
129
- items: [
130
- {
131
- codigo: '001',
132
- descripcion: 'Servicio de consultoria',
133
- cantidad: 1,
134
- unidadMedida: 7,
135
- precioUnitario: 200,
136
- importeItem: 200,
137
- codigoCondicionIVA: CodigoCondicionIVA.IVA_21,
138
- importeIVA: 42,
139
- },
140
- ],
141
- },
142
- });
143
- ```
99
+ ## Reglas de importes
144
100
 
145
- #### `ultimoComprobante(ptoVta, cbteTipo): Promise<number>`
101
+ Los campos del request se llaman igual que en el XSD (`ComprobanteType`, `ItemType`). Lo más importante del manual:
146
102
 
147
- Ultimo numero de comprobante autorizado.
103
+ - `importeItem` incluye el IVA. En clase A (1, 2, 3, 51, 52, 53) `precioUnitario` va **sin** IVA y el ítem lleva `importeIVA`; en clase B (6, 7, 8) `precioUnitario` va **con** IVA y el ítem no lleva `importeIVA`.
104
+ - `importeItem` = (`precioUnitario` × `cantidad` − `importeBonificacion`) × (1 + alícuota) en clase A; = `precioUnitario` × `cantidad` − `importeBonificacion` en clase B.
105
+ - Unidad 99 (bonificación) y 97 (seña): sin `cantidad`, `precioUnitario` ni `importeBonificacion`; la bonificación tiene `importeItem` negativo y requiere otro ítem con la misma condición de IVA. En clase A, `importeIVA` = `importeItem` − `importeItem` / (1 + alícuota).
106
+ - Fuera de 97/99, `unidadesMtx` y `codigoMtx` son obligatorios.
107
+ - `importeGravado` = Σ (`importeItem` − IVA) de los ítems con condición 3–6; `importeNoGravado` = Σ ítems condición 1; `importeExento` = Σ ítems condición 2; `importeSubtotal` = gravado + no gravado + exento.
108
+ - `subtotalesIVA`: uno por cada condición 4, 5 o 6 presente, con la suma del IVA de esos ítems.
109
+ - `importeTotal` = `importeSubtotal` + `importeOtrosTributos` + Σ subtotales de IVA = `importeOtrosTributos` + Σ `importeItem`.
110
+ - Margen de error del manual: error relativo ≤ 0,01% o absoluto ≤ 0,01 × cantidad de elementos.
148
111
 
149
- ```typescript
150
- const ultimo = await mtxca.ultimoComprobante(1, CbteTipo.FACTURA_B);
151
- ```
112
+ `autorizar()` valida todo esto antes de enviar y lanza `ArcaValidationError` con el detalle (incluye el código de error de ARCA que se evita y el valor esperado). Si ARCA acepta un caso que la validación local rechaza, pasá `{ validarImportes: false }`. Para redondear como el SDK: `roundImporte()` y `roundDecimal()`.
152
113
 
153
- #### `siguienteComprobante(ptoVta, cbteTipo): Promise<number>`
154
-
155
- Siguiente numero de comprobante (ultimo + 1).
114
+ Ejemplo de bonificación en clase A:
156
115
 
157
116
  ```typescript
158
- const siguiente = await mtxca.siguienteComprobante(1, CbteTipo.FACTURA_B);
117
+ items: [
118
+ { unidadesMtx: 1, codigoMtx: '7790001000012', descripcion: 'Producto', cantidad: 1, codigoUnidadMedida: 7,
119
+ precioUnitario: 100, codigoCondicionIVA: 5, importeIVA: 21, importeItem: 121 },
120
+ { descripcion: 'Bonificación 10%', codigoUnidadMedida: 99, codigoCondicionIVA: 5, importeIVA: -2.1, importeItem: -12.1 },
121
+ ],
122
+ importeGravado: 90, importeSubtotal: 90, importeTotal: 108.9,
123
+ subtotalesIVA: [{ codigo: 5, importe: 18.9 }],
159
124
  ```
160
125
 
161
- #### `consultarComprobante(cbteTipo, ptoVta, cbteNro): Promise<MtxcaComprobante>`
126
+ ## Resultado de una autorización y manejo de errores
162
127
 
163
- Consulta un comprobante previamente autorizado, incluyendo el detalle de items.
128
+ | Situación | Qué pasa |
129
+ | --- | --- |
130
+ | Datos inválidos localmente | `ArcaValidationError` (no se hace ningún request). |
131
+ | ARCA aprueba | `{ resultado: 'A', comprobante: { cae, fechaVencimientoCAE, ... } }` |
132
+ | ARCA aprueba con observaciones | `{ resultado: 'O', comprobante, observaciones }` |
133
+ | ARCA rechaza | `{ resultado: 'R', errores }` — **no lanza**; revisá `resultado`. |
134
+ | Consulta con `arrayErrores` | `ArcaServiceError` con `errors[]` (`code`, `msg`). |
135
+ | Fault SOAP, HTTP, red, timeout | `ArcaSoapError` (`uncertain`, `faultString`, `statusCode`). |
136
+ | Login WSAA | `ArcaAuthError` / `ArcaTicketVigenteError`. |
164
137
 
165
- ```typescript
166
- const comprobante = await mtxca.consultarComprobante(CbteTipo.FACTURA_B, 1, 150);
167
- console.log(comprobante.items); // Detalle de articulos
168
- ```
138
+ `ultimoComprobante()` devuelve 0 solo ante el error 1502 de ARCA ("no hay comprobantes para ese punto de venta y tipo"); cualquier otro error lanza.
169
139
 
170
- #### `status(): Promise<ServerStatus>`
140
+ ### Emisiones con resultado incierto
171
141
 
172
- Health check del servicio. No requiere autenticacion.
142
+ `autorizar`, `autorizarAjusteIVA`, `solicitarCAEA`, `informarComprobanteCAEA`, `informarAjusteIVACAEA`, `informarCAEANoUtilizado` e `informarCAEANoUtilizadoPtoVta` se envían una sola vez (nunca se reintentan). Si fallan con `ArcaSoapError` y `uncertain === true` (timeout, conexión cortada, HTTP 5xx, respuesta ilegible), ARCA pudo haber procesado el request. **No reintentes a ciegas**: si el comprobante ya fue autorizado, un reenvío con el mismo número es rechazado por correlatividad (102) y uno con el número siguiente duplica la factura.
173
143
 
174
144
  ```typescript
175
- const estado = await mtxca.status();
176
- console.log(estado.appserver); // "OK"
177
- ```
178
-
179
- ### Consulta de parametros
180
-
181
- ```typescript
182
- const tiposCbte = await mtxca.getTiposComprobante();
183
- const tiposDoc = await mtxca.getTiposDocumento();
184
- const alicuotas = await mtxca.getAlicuotasIVA();
185
- const condiciones = await mtxca.getCondicionesIVA();
186
- const monedas = await mtxca.getMonedas();
187
- const unidades = await mtxca.getUnidadesMedida();
188
- const ptosVenta = await mtxca.getPuntosVenta();
189
- const ptosVentaCAE = await mtxca.getPuntosVentaCAE();
190
- const ptosVentaCAEA = await mtxca.getPuntosVentaCAEA();
191
- const cotizacion = await mtxca.getCotizacionMoneda('DOL');
192
- ```
193
-
194
- ### Acceso a clientes de bajo nivel
195
-
196
- Para casos avanzados, se pueden usar los clientes individuales directamente:
197
-
198
- ```typescript
199
- const mtxca = new ArcaMtxca({ /* ... */ });
200
-
201
- // Obtener ticket de acceso manualmente
202
- const ticket = await mtxca.wsaa.getAccessTicket('wsmtxca');
203
-
204
- const auth = {
205
- Token: ticket.token,
206
- Sign: ticket.sign,
207
- Cuit: 20123456789,
208
- };
209
-
210
- // Llamar directamente al servicio
211
- const result = await mtxca.client.autorizarComprobante(auth, request);
212
- ```
213
-
214
- ## Tipos principales
145
+ import { ArcaSoapError } from '@ramiidv/arca-mtxca';
215
146
 
216
- ### MtxcaItem
217
-
218
- ```typescript
219
- interface MtxcaItem {
220
- codigo?: string; // Codigo/barcode del producto
221
- descripcion: string; // Descripcion del producto/servicio
222
- cantidad: number; // Cantidad
223
- unidadMedida: number; // Codigo unidad de medida
224
- precioUnitario: number; // Precio unitario
225
- importeItem: number; // Importe total del item
226
- codigoCondicionIVA: number; // Condicion de IVA del item
227
- importeIVA: number; // Importe de IVA del item
228
- importeBonificacion?: number; // Descuento
147
+ const numero = (await mtxca.ultimoComprobante(4000, CbteTipo.FACTURA_A)) + 1;
148
+ try {
149
+ return await mtxca.autorizar({ ...comprobante, numeroComprobante: numero });
150
+ } catch (e) {
151
+ if (e instanceof ArcaSoapError && e.uncertain) {
152
+ // ¿Llegó a autorizarse?
153
+ const ultimo = await mtxca.ultimoComprobante(4000, CbteTipo.FACTURA_A);
154
+ if (ultimo >= numero) {
155
+ const { comprobante } = await mtxca.consultarComprobante(CbteTipo.FACTURA_A, 4000, numero);
156
+ return comprobante; // codigoAutorizacion = CAE
157
+ }
158
+ // No se autorizó: se puede reenviar con el mismo número.
159
+ }
160
+ throw e;
229
161
  }
230
162
  ```
231
163
 
232
- ### MtxcaInvoiceResult
164
+ Para CAEA: `solicitarCAEA` incierto → `consultarCAEAEntreFechas()`; `informarComprobanteCAEA` incierto → `consultarComprobante()`.
233
165
 
234
- ```typescript
235
- interface MtxcaInvoiceResult {
236
- resultado: string; // "A" = Aprobado, "R" = Rechazado
237
- cae?: string; // CAE otorgado
238
- caeFchVto?: string; // Vencimiento del CAE (YYYY-MM-DD)
239
- cbteNro: number; // Numero de comprobante
240
- observaciones: MtxcaObservacion[];
241
- errores: MtxcaObservacion[];
242
- }
243
- ```
166
+ Las solicitudes de un mismo punto de venta y tipo deben ser secuenciales (ARCA rechaza con 135 una solicitud concurrente), y la numeración automática supone un único emisor por punto de venta.
244
167
 
245
- ### MtxcaComprobante
168
+ ## API
246
169
 
247
- ```typescript
248
- interface MtxcaComprobante {
249
- codigoTipoComprobante: number;
250
- numeroPuntoVenta: number;
251
- numeroComprobante: number;
252
- fechaEmision: string;
253
- codigoTipoDocumento: number;
254
- numeroDocumento: number;
255
- importeTotal: number;
256
- importeNoGravado: number;
257
- importeGravado: number;
258
- importeExento: number;
259
- importeOtrosTributos: number;
260
- importeSubtotal: number;
261
- codigoMoneda: string;
262
- cotizacionMoneda: number;
263
- resultado: string;
264
- codigoAutorizacion?: string;
265
- fechaVencimiento?: string;
266
- observaciones: MtxcaObservacion[];
267
- items: MtxcaItem[];
268
- }
269
- ```
170
+ ### Comprobantes con CAE
270
171
 
271
- ## Manejo de errores
172
+ | Método | Operación WSMTXCA |
173
+ | --- | --- |
174
+ | `autorizar(req, opts?)` | `autorizarComprobante` (número automático si se omite) |
175
+ | `autorizarAjusteIVA(req, opts?)` | `autorizarAjusteIVA` (solo valida el XSD: tiene reglas propias) |
176
+ | `ultimoComprobante(ptoVta, cbteTipo, opts?)` | `consultarUltimoComprobanteAutorizado` |
177
+ | `siguienteComprobante(ptoVta, cbteTipo, opts?)` | último + 1 |
178
+ | `consultarComprobante(cbteTipo, ptoVta, cbteNro, opts?)` | `consultarComprobante` → `{ comprobante, observaciones, evento? }` |
272
179
 
273
- El SDK usa la jerarquia de errores de `@ramiidv/arca-common`:
180
+ ### CAEA
274
181
 
275
- ```
276
- Error
277
- └── ArcaError (base)
278
- ├── ArcaAuthError (errores de WSAA)
279
- ├── ArcaServiceError (errores de negocio)
280
- └── ArcaSoapError (errores HTTP/transporte)
281
- ```
182
+ | Método | Operación WSMTXCA |
183
+ | --- | --- |
184
+ | `solicitarCAEA(periodo, orden, opts?)` | `solicitarCAEA` (`periodo` AAAAMM, `orden` 1 o 2) |
185
+ | `consultarCAEA(caea, opts?)` | `consultarCAEA` |
186
+ | `consultarCAEAEntreFechas(desde, hasta, opts?)` | `consultarCAEAEntreFechas` |
187
+ | `informarComprobanteCAEA(comp, opts?)` | `informarComprobanteCAEA` (`comp.caea` = CAEA usado) |
188
+ | `informarAjusteIVACAEA(comp, opts?)` | `informarAjusteIVACAEA` |
189
+ | `informarCAEANoUtilizado(caea, opts?)` | `informarCAEANoUtilizado` |
190
+ | `informarCAEANoUtilizadoPtoVta(caea, ptoVta, opts?)` | `informarCAEANoUtilizadoPtoVta` |
191
+ | `consultarPtosVtaCAEANoInformados(caea, opts?)` | `consultarPtosVtaCAEANoInformados` |
282
192
 
283
- ```typescript
284
- import { ArcaAuthError, ArcaServiceError, ArcaSoapError } from '@ramiidv/arca-mtxca';
193
+ ### Parámetros y estado
285
194
 
286
- try {
287
- await mtxca.autorizar(request);
288
- } catch (error) {
289
- if (error instanceof ArcaAuthError) {
290
- // Certificado vencido, servicio no autorizado, WSAA caido
291
- console.error('Error de autenticacion:', error.message);
292
- } else if (error instanceof ArcaServiceError) {
293
- // Errores de negocio (comprobante rechazado, etc.)
294
- for (const detalle of error.errors) {
295
- console.error(`[${detalle.code}] ${detalle.msg}`);
296
- }
297
- } else if (error instanceof ArcaSoapError) {
298
- // Errores HTTP/red
299
- console.error('Error HTTP:', error.statusCode, error.message);
300
- }
301
- }
302
- ```
195
+ | Método | Operación | Devuelve |
196
+ | --- | --- | --- |
197
+ | `status()` | `dummy` (sin auth) | `{ appserver, dbserver, authserver }` |
198
+ | `getTiposComprobante()` | `consultarTiposComprobante` | `CodigoDescripcion[]` |
199
+ | `getTiposDocumento()` | `consultarTiposDocumento` | `CodigoDescripcion[]` |
200
+ | `getAlicuotasIVA()` | `consultarAlicuotasIVA` | `CodigoDescripcion[]` |
201
+ | `getCondicionesIVA()` | `consultarCondicionesIVA` | `CodigoDescripcion[]` |
202
+ | `getCondicionesIVAReceptor(cbteTipo)` | `consultarCondicionesIVAReceptor` | `CodigoDescripcion[]` |
203
+ | `getMonedas()` | `consultarMonedas` | `{ codigo: string, descripcion }[]` |
204
+ | `getCotizacionMoneda(codigo, fecha?)` | `consultarCotizacionMoneda` | `{ codigoMoneda, fechaCotizacion, cotizacion: number \| null }` |
205
+ | `getUnidadesMedida()` | `consultarUnidadesMedida` | `CodigoDescripcion[]` |
206
+ | `getTiposTributo()` | `consultarTiposTributo` | `CodigoDescripcion[]` |
207
+ | `getTiposDatosAdicionales()` | `consultarTiposDatosAdicionales` | `CodigoDescripcion[]` |
208
+ | `getActividadesVigentes()` | `consultarActividadesVigentes` | `{ codigo, orden, descripcion }[]` |
209
+ | `getPuntosVenta()` / `getPuntosVentaCAE()` / `getPuntosVentaCAEA()` | `consultarPuntosVenta*` | `{ numeroPuntoVenta, bloqueado, fechaBaja? }[]` |
303
210
 
304
- Ademas, las respuestas de `autorizar()` pueden tener `resultado === 'R'` con observaciones/errores sin lanzar excepcion. Siempre verificar `result.resultado`:
211
+ `getCotizacionMoneda` usa la fecha de hoy si no se indica; `cotizacion` es `null` cuando ARCA no tiene cotización (responde sin valor y sin error).
305
212
 
306
- ```typescript
307
- const result = await mtxca.autorizar(request);
308
- if (result.resultado !== 'A') {
309
- console.error('Rechazado:', result.errores);
310
- console.warn('Observaciones:', result.observaciones);
311
- }
312
- ```
213
+ `clearAuthCache()` (async) descarta el ticket WSAA de `wsmtxca`.
214
+
215
+ ### Cliente de bajo nivel
313
216
 
314
- ## Eventos
217
+ `mtxca.client` (`MtxcaClient`) expone una función por operación del WSDL (`autorizarComprobante`, `consultarCAEA`, ...) que recibe `MtxcaAuth` (`{ token, sign, cuitRepresentada }`) y `numeroComprobante` explícito. Valida contra el XSD y redondea, pero no valida la coherencia de importes. Se puede usar sin `ArcaMtxca`:
315
218
 
316
219
  ```typescript
317
- const mtxca = new ArcaMtxca({
318
- // ...
319
- onEvent: (evento) => {
320
- switch (evento.type) {
321
- case 'auth:login':
322
- console.log(`Login para ${evento.service}`);
323
- break;
324
- case 'auth:cache-hit':
325
- console.log(`Token cacheado para ${evento.service}`);
326
- break;
327
- case 'request:start':
328
- console.log(`Inicio ${evento.method}`);
329
- break;
330
- case 'request:end':
331
- console.log(`Fin ${evento.method} (${evento.durationMs}ms)`);
332
- break;
333
- case 'request:retry':
334
- console.log(`Reintento #${evento.attempt}`);
335
- break;
336
- case 'request:error':
337
- console.error(`Error: ${evento.error}`);
338
- break;
339
- }
340
- },
341
- });
220
+ import { MtxcaClient, MTXCA_ENDPOINTS } from '@ramiidv/arca-mtxca';
221
+ const client = new MtxcaClient({ endpoint: MTXCA_ENDPOINTS.testing });
222
+ await client.dummy();
342
223
  ```
343
224
 
344
- ## Enums utiles
225
+ ## Enums y constantes
345
226
 
346
- ```typescript
347
- import { CbteTipo, Concepto, CodigoCondicionIVA, Moneda } from '@ramiidv/arca-mtxca';
348
-
349
- // Tipos de comprobante
350
- CbteTipo.FACTURA_A // 1
351
- CbteTipo.NOTA_DEBITO_A // 2
352
- CbteTipo.NOTA_CREDITO_A // 3
353
- CbteTipo.FACTURA_B // 6
354
- CbteTipo.NOTA_DEBITO_B // 7
355
- CbteTipo.NOTA_CREDITO_B // 8
356
-
357
- // Concepto
358
- Concepto.PRODUCTOS // 1
359
- Concepto.SERVICIOS // 2
360
- Concepto.PRODUCTOS_Y_SERVICIOS // 3
361
-
362
- // Condicion IVA del item
363
- CodigoCondicionIVA.NO_GRAVADO // 1
364
- CodigoCondicionIVA.EXENTO // 2
365
- CodigoCondicionIVA.IVA_0 // 3
366
- CodigoCondicionIVA.IVA_10_5 // 4
367
- CodigoCondicionIVA.IVA_21 // 5
368
- CodigoCondicionIVA.IVA_27 // 6
369
- CodigoCondicionIVA.GRAVADO // 7
370
- CodigoCondicionIVA.IVA_5 // 8
371
- CodigoCondicionIVA.IVA_2_5 // 9
372
-
373
- // Monedas
374
- Moneda.PESOS // "PES"
375
- Moneda.DOLARES // "DOL"
376
- Moneda.EUROS // "060"
377
- ```
227
+ - `CbteTipo`: 1, 2, 3, 6, 7, 8, 51, 52, 53 (A con leyenda "OPERACIÓN SUJETA A RETENCIÓN") y FCE 201–203, 206–208.
228
+ - `Concepto`: 1 productos, 2 servicios, 3 ambos.
229
+ - `CodigoCondicionIVA`: 1 no gravado, 2 exento, 3 0%, 4 10,5%, 5 21%, 6 27% (y `ALICUOTAS_IVA`).
230
+ - `UnidadMedidaEspecial`: 95, 97 (seña), 99 (bonificación).
231
+ - `Moneda`: `PES`, `DOL`, `060` (euro). Lista completa: `getMonedas()`.
378
232
 
379
233
  ## Requisitos
380
234
 
381
- - Node.js >= 18 (soporte nativo de `fetch`)
382
- - Certificado digital emitido por ARCA/AFIP
383
- - Autorizacion para el servicio `wsmtxca`
235
+ - Node.js >= 18.
236
+ - Certificado digital de ARCA asociado al servicio `wsmtxca` y empadronamiento en "Codificación de Productos – Factura con Detalle".
384
237
 
385
238
  ## Licencia
386
239