@ramiidv/arca-mtxca 0.1.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 +171 -318
- package/dist/arca-mtxca.d.ts +83 -75
- package/dist/arca-mtxca.d.ts.map +1 -1
- package/dist/arca-mtxca.js +197 -141
- package/dist/arca-mtxca.js.map +1 -1
- package/dist/constants.d.ts +37 -21
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +49 -22
- package/dist/constants.js.map +1 -1
- package/dist/format.d.ts +18 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +65 -0
- package/dist/format.js.map +1 -0
- package/dist/index.d.ts +7 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -10
- package/dist/index.js.map +1 -1
- package/dist/mtxca-client.d.ts +90 -32
- package/dist/mtxca-client.d.ts.map +1 -1
- package/dist/mtxca-client.js +416 -324
- package/dist/mtxca-client.js.map +1 -1
- package/dist/parse.d.ts +31 -0
- package/dist/parse.d.ts.map +1 -0
- package/dist/parse.js +82 -0
- package/dist/parse.js.map +1 -0
- package/dist/serialize.d.ts +43 -0
- package/dist/serialize.d.ts.map +1 -0
- package/dist/serialize.js +323 -0
- package/dist/serialize.js.map +1 -0
- package/dist/types.d.ts +314 -174
- package/dist/types.d.ts.map +1 -1
- package/dist/validation.d.ts +16 -7
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +292 -92
- package/dist/validation.js.map +1 -1
- package/llms.txt +81 -159
- package/package.json +5 -4
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)
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
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:
|
|
43
|
-
production: false, //
|
|
28
|
+
cuit: '20-12345678-6',
|
|
29
|
+
production: false, // homologación
|
|
44
30
|
});
|
|
45
31
|
|
|
46
|
-
//
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
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 (
|
|
78
|
-
console.
|
|
79
|
-
|
|
80
|
-
|
|
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
|
-
##
|
|
73
|
+
## Configuración
|
|
85
74
|
|
|
86
|
-
|
|
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
|
-
|
|
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
|
-
|
|
90
|
+
Endpoints (manual WSMTXCA):
|
|
110
91
|
|
|
111
|
-
|
|
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
|
-
|
|
97
|
+
Todos los métodos aceptan un último parámetro `opts?: CallOptions` con `signal` para cancelar.
|
|
114
98
|
|
|
115
|
-
|
|
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
|
-
|
|
101
|
+
Los campos del request se llaman igual que en el XSD (`ComprobanteType`, `ItemType`). Lo más importante del manual:
|
|
146
102
|
|
|
147
|
-
|
|
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
|
-
|
|
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
|
-
|
|
154
|
-
|
|
155
|
-
Siguiente numero de comprobante (ultimo + 1).
|
|
114
|
+
Ejemplo de bonificación en clase A:
|
|
156
115
|
|
|
157
116
|
```typescript
|
|
158
|
-
|
|
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
|
-
|
|
126
|
+
## Resultado de una autorización y manejo de errores
|
|
162
127
|
|
|
163
|
-
|
|
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
|
-
|
|
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
|
-
|
|
140
|
+
### Emisiones con resultado incierto
|
|
171
141
|
|
|
172
|
-
|
|
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
|
-
|
|
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
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
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
|
-
|
|
164
|
+
Para CAEA: `solicitarCAEA` incierto → `consultarCAEAEntreFechas()`; `informarComprobanteCAEA` incierto → `consultarComprobante()`.
|
|
233
165
|
|
|
234
|
-
|
|
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
|
-
|
|
168
|
+
## API
|
|
246
169
|
|
|
247
|
-
|
|
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
|
-
|
|
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
|
-
|
|
180
|
+
### CAEA
|
|
274
181
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
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
|
-
|
|
284
|
-
import { ArcaAuthError, ArcaServiceError, ArcaSoapError } from '@ramiidv/arca-mtxca';
|
|
193
|
+
### Parámetros y estado
|
|
285
194
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
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
|
-
|
|
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
|
-
|
|
307
|
-
|
|
308
|
-
|
|
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
|
-
|
|
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
|
-
|
|
318
|
-
|
|
319
|
-
|
|
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
|
|
225
|
+
## Enums y constantes
|
|
345
226
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
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
|
|
382
|
-
- Certificado digital
|
|
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
|
|