@ramiidv/arca-sdk 0.2.1 → 1.0.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 +151 -8
- package/dist/arca.d.ts +72 -127
- package/dist/arca.d.ts.map +1 -1
- package/dist/arca.js +167 -149
- package/dist/arca.js.map +1 -1
- package/dist/constants.d.ts +5 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +5 -0
- package/dist/constants.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/soap-client.d.ts +13 -6
- package/dist/soap-client.d.ts.map +1 -1
- package/dist/soap-client.js +79 -32
- package/dist/soap-client.js.map +1 -1
- package/dist/types.d.ts +207 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/wsaa.d.ts +6 -2
- package/dist/wsaa.d.ts.map +1 -1
- package/dist/wsaa.js +25 -6
- package/dist/wsaa.js.map +1 -1
- package/dist/wsfe.d.ts +10 -45
- package/dist/wsfe.d.ts.map +1 -1
- package/dist/wsfe.js +40 -99
- package/dist/wsfe.js.map +1 -1
- package/dist/wsfex.d.ts +50 -0
- package/dist/wsfex.d.ts.map +1 -0
- package/dist/wsfex.js +141 -0
- package/dist/wsfex.js.map +1 -0
- package/llm.txt +466 -0
- package/package.json +8 -7
package/llm.txt
ADDED
|
@@ -0,0 +1,466 @@
|
|
|
1
|
+
# @ramiidv/arca-sdk
|
|
2
|
+
|
|
3
|
+
> TypeScript SDK for ARCA (formerly AFIP) electronic invoicing in Argentina.
|
|
4
|
+
> Wraps WSFEv1, WSFEX, and WSAA SOAP web services.
|
|
5
|
+
|
|
6
|
+
## What this SDK does
|
|
7
|
+
|
|
8
|
+
- Authenticates against ARCA's WSAA using X.509 certificates (PKCS#7/CMS signing)
|
|
9
|
+
- Creates electronic invoices (facturas), credit notes, and debit notes via WSFEv1
|
|
10
|
+
- Handles all comprobante types: A, B, C, E, M, and MiPyME FCE
|
|
11
|
+
- Auto-calculates IVA, totals, and comprobante numbers
|
|
12
|
+
- Queries ARCA parameters (document types, IVA rates, currencies, exchange rates, etc.)
|
|
13
|
+
- Export invoices via WSFEX (Factura de Exportación)
|
|
14
|
+
- Retry with exponential backoff on transient errors
|
|
15
|
+
- Event system for logging/debugging (auth, requests, retries)
|
|
16
|
+
- QR code URL generation for printed invoices
|
|
17
|
+
|
|
18
|
+
## Install
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install @ramiidv/arca-sdk
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Requires Node.js >= 18. Uses native `fetch` (no axios/node-fetch dependency).
|
|
25
|
+
|
|
26
|
+
## Quick start
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
import fs from "fs";
|
|
30
|
+
import { Arca, CbteTipo, IvaTipo, DocTipo, Moneda } from "@ramiidv/arca-sdk";
|
|
31
|
+
|
|
32
|
+
const arca = new Arca({
|
|
33
|
+
cuit: 20123456789,
|
|
34
|
+
cert: fs.readFileSync("./cert.crt", "utf-8"),
|
|
35
|
+
key: fs.readFileSync("./key.key", "utf-8"),
|
|
36
|
+
production: false,
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
const result = await arca.facturar({
|
|
40
|
+
ptoVta: 1,
|
|
41
|
+
cbteTipo: CbteTipo.FACTURA_B,
|
|
42
|
+
items: [{ neto: 1000, iva: IvaTipo.IVA_21 }],
|
|
43
|
+
});
|
|
44
|
+
// result: { aprobada: true, cae: "...", cbteNro: 42, importes: { total: 1210, neto: 1000, iva: 210, ... } }
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Architecture
|
|
48
|
+
|
|
49
|
+
The SDK has two API levels:
|
|
50
|
+
|
|
51
|
+
1. **Simplified API** (`facturar`, `notaCredito`, `notaDebito`) — auto-calculates IVA, totals, comprobante number, dates. Returns a clean `FacturaResult`.
|
|
52
|
+
2. **Raw API** (`crearFactura`, `crearFacturaAuto`) — maps 1:1 to AFIP's WSFEv1 SOAP methods. Returns raw AFIP XML responses parsed to JS objects.
|
|
53
|
+
|
|
54
|
+
Internally:
|
|
55
|
+
- `Arca` (main class) — orchestrator, holds config, exposes all methods
|
|
56
|
+
- `WsaaClient` — handles WSAA authentication, token caching with dedup and expiry margin
|
|
57
|
+
- `WsfeClient` — wraps all WSFEv1 SOAP calls
|
|
58
|
+
- `facturacion.ts` — pure functions for IVA/total calculation and invoice building
|
|
59
|
+
- `soap-client.ts` — generic SOAP/XML utilities (fetch with timeout, XML parsing via fast-xml-parser)
|
|
60
|
+
- `errors.ts` — `ArcaAuthError`, `ArcaWSFEError` (with error codes), `ArcaSoapError` (with HTTP status)
|
|
61
|
+
|
|
62
|
+
## Configuration
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
new Arca({
|
|
66
|
+
cuit: number, // CUIT without hyphens
|
|
67
|
+
cert: string, // X.509 certificate PEM content
|
|
68
|
+
key: string, // Private key PEM content
|
|
69
|
+
production?: boolean, // Default: false (uses homologación/testing endpoints)
|
|
70
|
+
tokenTTLMinutes?: number, // Default: 720 (12 hours)
|
|
71
|
+
requestTimeoutMs?: number, // Default: 30000 (30 seconds). Uses AbortController.
|
|
72
|
+
retries?: number, // Default: 1. Retries on transient errors (timeout, 5xx).
|
|
73
|
+
retryDelayMs?: number, // Default: 1000. Exponential backoff: delay * 2^attempt.
|
|
74
|
+
onEvent?: (event: ArcaEvent) => void, // Callback for all SDK events
|
|
75
|
+
})
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Simplified API — facturar()
|
|
79
|
+
|
|
80
|
+
Automatically: gets next comprobante number, calculates all totals from line items, formats dates in Argentina timezone, defaults to Consumidor Final + Pesos + Productos.
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
interface FacturarOpts {
|
|
84
|
+
ptoVta: number; // Punto de venta
|
|
85
|
+
cbteTipo: number; // CbteTipo enum
|
|
86
|
+
items: LineItem[]; // Line items (see below)
|
|
87
|
+
concepto?: number; // Default: PRODUCTOS. Auto-detects SERVICIOS if `servicio` provided
|
|
88
|
+
docTipo?: number; // Default: DocTipo.CONSUMIDOR_FINAL (99)
|
|
89
|
+
docNro?: number; // Default: 0
|
|
90
|
+
fecha?: Date | string; // Default: today (Argentina timezone). String = "YYYYMMDD"
|
|
91
|
+
servicio?: { desde, hasta, vtoPago }; // Required for services. Accepts Date or "YYYYMMDD"
|
|
92
|
+
moneda?: string; // Default: "PES"
|
|
93
|
+
cotizacion?: number; // Default: 1
|
|
94
|
+
tributos?: Tributo[];
|
|
95
|
+
opcionales?: Opcional[]; // E.g., CBU for FCE: [{ Id: "2101", Valor: "..." }]
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
interface LineItem {
|
|
99
|
+
neto: number; // Net amount (without IVA)
|
|
100
|
+
iva?: number; // IvaTipo enum. If set, item is "gravado" and IVA is calculated
|
|
101
|
+
exento?: boolean; // If true, amount goes to ImpOpEx (exempt)
|
|
102
|
+
// If neither iva nor exento: amount goes to ImpTotConc (no gravado)
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**IVA calculation rules:**
|
|
107
|
+
- Items with `iva` set → added to ImpNeto. IVA calculated using IVA_RATES and added to ImpIVA. Grouped by aliquot in the Iva array.
|
|
108
|
+
- Items with `exento: true` → added to ImpOpEx.
|
|
109
|
+
- Items with neither → added to ImpTotConc (no gravado).
|
|
110
|
+
- ImpTotal = ImpNeto + ImpIVA + ImpOpEx + ImpTotConc + ImpTrib.
|
|
111
|
+
- All amounts rounded to 2 decimal places.
|
|
112
|
+
- For CbteTipo C (monotributista): IVA is NOT discriminated. All items go to ImpNeto, ImpIVA = 0.
|
|
113
|
+
|
|
114
|
+
**Return type:**
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
interface FacturaResult {
|
|
118
|
+
aprobada: boolean;
|
|
119
|
+
cae?: string;
|
|
120
|
+
caeVencimiento?: string; // "YYYYMMDD"
|
|
121
|
+
cbteNro: number;
|
|
122
|
+
ptoVta: number;
|
|
123
|
+
cbteTipo: number;
|
|
124
|
+
importes: {
|
|
125
|
+
total: number;
|
|
126
|
+
neto: number;
|
|
127
|
+
iva: number;
|
|
128
|
+
exento: number;
|
|
129
|
+
noGravado: number;
|
|
130
|
+
tributos: number;
|
|
131
|
+
};
|
|
132
|
+
observaciones: { code: number; msg: string }[];
|
|
133
|
+
raw: FECAESolicitarResult; // Full AFIP response
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Simplified API — notaCredito() / notaDebito()
|
|
138
|
+
|
|
139
|
+
Same as `facturar` but with `comprobanteOriginal` instead of `cbteTipo`. The NC/ND type is inferred automatically (FACTURA_B → NOTA_CREDITO_B, etc.).
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
await arca.notaCredito({
|
|
143
|
+
ptoVta: 1,
|
|
144
|
+
comprobanteOriginal: { tipo: CbteTipo.FACTURA_B, ptoVta: 1, nro: 150 },
|
|
145
|
+
items: [{ neto: 100, iva: IvaTipo.IVA_21 }],
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
await arca.notaDebito({
|
|
149
|
+
ptoVta: 1,
|
|
150
|
+
comprobanteOriginal: { tipo: CbteTipo.FACTURA_A, ptoVta: 1, nro: 200, fecha: "20260301" },
|
|
151
|
+
docTipo: DocTipo.CUIT,
|
|
152
|
+
docNro: 30712345678,
|
|
153
|
+
items: [{ neto: 500, iva: IvaTipo.IVA_21 }],
|
|
154
|
+
});
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
**Supported CbteTipo mappings:**
|
|
158
|
+
- FACTURA_A (1) → NC_A (3), ND_A (2)
|
|
159
|
+
- FACTURA_B (6) → NC_B (8), ND_B (7)
|
|
160
|
+
- FACTURA_C (11) → NC_C (13), ND_C (12)
|
|
161
|
+
- FACTURA_E (19) → NC_E (21), ND_E (20)
|
|
162
|
+
- FACTURA_M (51) → NC_M (53), ND_M (52)
|
|
163
|
+
- FCE_FACTURA_A (201) → FCE_NC_A (203), FCE_ND_A (202)
|
|
164
|
+
- FCE_FACTURA_B (206) → FCE_NC_B (208), FCE_ND_B (207)
|
|
165
|
+
- FCE_FACTURA_C (211) → FCE_NC_C (213), FCE_ND_C (212)
|
|
166
|
+
|
|
167
|
+
## Static utilities
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
// Preview totals without submitting to ARCA
|
|
171
|
+
const { importes, iva } = Arca.calcularTotales(
|
|
172
|
+
[{ neto: 1000, iva: IvaTipo.IVA_21 }],
|
|
173
|
+
{ tributos: [...], tipoC: false }
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
// Format date to YYYYMMDD in Argentina timezone
|
|
177
|
+
Arca.formatDate(new Date()); // "20260328"
|
|
178
|
+
Arca.formatDate("20260328"); // passthrough
|
|
179
|
+
|
|
180
|
+
// Extract CAE from raw result (for raw API users)
|
|
181
|
+
const { approved, cae, caeFchVto, details } = Arca.extractCAE(rawResult);
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## Raw API (advanced)
|
|
185
|
+
|
|
186
|
+
Maps directly to WSFEv1 SOAP methods. No auto-calculation. User must provide all fields.
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
// Get next number manually
|
|
190
|
+
const nextNum = await arca.siguienteComprobante(1, CbteTipo.FACTURA_B);
|
|
191
|
+
|
|
192
|
+
// Create invoice with full control
|
|
193
|
+
const rawResult = await arca.crearFactura({
|
|
194
|
+
PtoVta: 1,
|
|
195
|
+
CbteTipo: CbteTipo.FACTURA_B,
|
|
196
|
+
invoices: [{
|
|
197
|
+
Concepto: 1, DocTipo: 99, DocNro: 0,
|
|
198
|
+
CbteDesde: nextNum, CbteHasta: nextNum,
|
|
199
|
+
CbteFch: "20260328",
|
|
200
|
+
ImpTotal: 121, ImpTotConc: 0, ImpNeto: 100,
|
|
201
|
+
ImpOpEx: 0, ImpTrib: 0, ImpIVA: 21,
|
|
202
|
+
MonId: "PES", MonCotiz: 1,
|
|
203
|
+
Iva: [{ Id: 5, BaseImp: 100, Importe: 21 }],
|
|
204
|
+
}],
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
// Or with auto-numbering (still no auto-calc)
|
|
208
|
+
const rawResult2 = await arca.crearFacturaAuto(1, CbteTipo.FACTURA_B, { ...invoiceDetail });
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## Query methods
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
await arca.serverStatus(); // { AppServer, DbServer, AuthServer }
|
|
215
|
+
await arca.ultimoComprobante(ptoVta, cbteTipo); // number
|
|
216
|
+
await arca.consultarComprobante(cbteTipo, ptoVta, cbteNro);
|
|
217
|
+
await arca.getPuntosVenta();
|
|
218
|
+
await arca.getCotizacion(Moneda.DOLARES); // { MonId, MonCotiz, FchCotiz }
|
|
219
|
+
await arca.getTiposComprobante();
|
|
220
|
+
await arca.getTiposConcepto();
|
|
221
|
+
await arca.getTiposDocumento();
|
|
222
|
+
await arca.getTiposIva();
|
|
223
|
+
await arca.getMonedas();
|
|
224
|
+
await arca.getTiposTributo();
|
|
225
|
+
await arca.getTiposOpcional();
|
|
226
|
+
await arca.getCantMaxRegistros();
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Error handling
|
|
230
|
+
|
|
231
|
+
```typescript
|
|
232
|
+
import { ArcaAuthError, ArcaWSFEError, ArcaSoapError } from "@ramiidv/arca-sdk";
|
|
233
|
+
|
|
234
|
+
try {
|
|
235
|
+
await arca.facturar({ ... });
|
|
236
|
+
} catch (e) {
|
|
237
|
+
if (e instanceof ArcaAuthError) {
|
|
238
|
+
// WSAA login failed (bad cert, expired, etc.)
|
|
239
|
+
arca.clearAuthCache();
|
|
240
|
+
}
|
|
241
|
+
if (e instanceof ArcaWSFEError) {
|
|
242
|
+
// AFIP business error with codes
|
|
243
|
+
e.errors; // { code: number, msg: string }[]
|
|
244
|
+
}
|
|
245
|
+
if (e instanceof ArcaSoapError) {
|
|
246
|
+
// HTTP/SOAP transport error (timeout, 500, SOAP fault)
|
|
247
|
+
e.statusCode; // number | undefined
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
All error classes extend `ArcaError` which extends `Error`.
|
|
253
|
+
|
|
254
|
+
## Enums reference
|
|
255
|
+
|
|
256
|
+
```typescript
|
|
257
|
+
// Comprobante types
|
|
258
|
+
CbteTipo.FACTURA_A // 1
|
|
259
|
+
CbteTipo.FACTURA_B // 6
|
|
260
|
+
CbteTipo.FACTURA_C // 11
|
|
261
|
+
CbteTipo.FACTURA_E // 19 (export)
|
|
262
|
+
CbteTipo.FCE_FACTURA_A // 201 (MiPyME)
|
|
263
|
+
// ... and NOTA_DEBITO_*, NOTA_CREDITO_*, RECIBO_* variants
|
|
264
|
+
|
|
265
|
+
// Concepto
|
|
266
|
+
Concepto.PRODUCTOS // 1
|
|
267
|
+
Concepto.SERVICIOS // 2
|
|
268
|
+
Concepto.PRODUCTOS_Y_SERVICIOS // 3
|
|
269
|
+
|
|
270
|
+
// Document types
|
|
271
|
+
DocTipo.CUIT // 80
|
|
272
|
+
DocTipo.DNI // 96
|
|
273
|
+
DocTipo.CONSUMIDOR_FINAL // 99
|
|
274
|
+
// ... CUIL (86), CDI (87), Pasaporte (94), etc.
|
|
275
|
+
|
|
276
|
+
// IVA rates
|
|
277
|
+
IvaTipo.IVA_0 // 3 → 0%
|
|
278
|
+
IvaTipo.IVA_2_5 // 9 → 2.5%
|
|
279
|
+
IvaTipo.IVA_5 // 8 → 5%
|
|
280
|
+
IvaTipo.IVA_10_5 // 4 → 10.5%
|
|
281
|
+
IvaTipo.IVA_21 // 5 → 21%
|
|
282
|
+
IvaTipo.IVA_27 // 6 → 27%
|
|
283
|
+
|
|
284
|
+
// IVA_RATES maps IvaTipo to percentage: IVA_RATES[IvaTipo.IVA_21] === 21
|
|
285
|
+
|
|
286
|
+
// Currency
|
|
287
|
+
Moneda.PESOS // "PES"
|
|
288
|
+
Moneda.DOLARES // "DOL"
|
|
289
|
+
Moneda.EUROS // "060"
|
|
290
|
+
// ... and more
|
|
291
|
+
|
|
292
|
+
// Tributo types
|
|
293
|
+
TributoTipo.IIBB // 5
|
|
294
|
+
TributoTipo.PERCEP_IVA // 6
|
|
295
|
+
// ... and more
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
## Common patterns
|
|
299
|
+
|
|
300
|
+
### Service invoice with tributos
|
|
301
|
+
|
|
302
|
+
```typescript
|
|
303
|
+
await arca.facturar({
|
|
304
|
+
ptoVta: 1,
|
|
305
|
+
cbteTipo: CbteTipo.FACTURA_A,
|
|
306
|
+
docTipo: DocTipo.CUIT,
|
|
307
|
+
docNro: 30712345678,
|
|
308
|
+
items: [{ neto: 10000, iva: IvaTipo.IVA_21 }],
|
|
309
|
+
servicio: {
|
|
310
|
+
desde: new Date("2026-03-01"),
|
|
311
|
+
hasta: new Date("2026-03-31"),
|
|
312
|
+
vtoPago: new Date("2026-04-15"),
|
|
313
|
+
},
|
|
314
|
+
tributos: [{
|
|
315
|
+
Id: TributoTipo.IIBB,
|
|
316
|
+
Desc: "IIBB CABA",
|
|
317
|
+
BaseImp: 10000,
|
|
318
|
+
Alic: 3,
|
|
319
|
+
Importe: 300,
|
|
320
|
+
}],
|
|
321
|
+
});
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### Batch invoice (raw API, multiple comprobantes)
|
|
325
|
+
|
|
326
|
+
```typescript
|
|
327
|
+
const result = await arca.crearFactura({
|
|
328
|
+
PtoVta: 1,
|
|
329
|
+
CbteTipo: CbteTipo.FACTURA_B,
|
|
330
|
+
invoices: [invoice1, invoice2, invoice3], // up to getCantMaxRegistros()
|
|
331
|
+
});
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### Currency with exchange rate
|
|
335
|
+
|
|
336
|
+
```typescript
|
|
337
|
+
const cotiz = await arca.getCotizacion(Moneda.DOLARES);
|
|
338
|
+
await arca.facturar({
|
|
339
|
+
ptoVta: 1,
|
|
340
|
+
cbteTipo: CbteTipo.FACTURA_A,
|
|
341
|
+
docTipo: DocTipo.CUIT,
|
|
342
|
+
docNro: 30712345678,
|
|
343
|
+
items: [{ neto: 1000, iva: IvaTipo.IVA_21 }],
|
|
344
|
+
moneda: Moneda.DOLARES,
|
|
345
|
+
cotizacion: cotiz.MonCotiz,
|
|
346
|
+
});
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
## Events / Logging
|
|
350
|
+
|
|
351
|
+
Two ways to subscribe:
|
|
352
|
+
|
|
353
|
+
```typescript
|
|
354
|
+
// 1. Config callback (receives all events)
|
|
355
|
+
const arca = new Arca({
|
|
356
|
+
...,
|
|
357
|
+
onEvent: (e) => console.log(e.type, e),
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
// 2. Typed .on()/.off() (filter by event type)
|
|
361
|
+
arca.on("request:end", (e) => console.log(`${e.method} took ${e.durationMs}ms`));
|
|
362
|
+
arca.on("auth:login", (e) => console.log(`Login ${e.service} in ${e.durationMs}ms`));
|
|
363
|
+
arca.on("request:retry", (e) => console.warn(`Retry #${e.attempt}: ${e.error}`));
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
Event types (discriminated union `ArcaEvent`):
|
|
367
|
+
- `auth:login` — new token obtained. Fields: `service`, `durationMs`
|
|
368
|
+
- `auth:cache-hit` — cached token reused. Fields: `service`
|
|
369
|
+
- `request:start` — SOAP call starting. Fields: `method`, `endpoint`
|
|
370
|
+
- `request:end` — SOAP call completed. Fields: `method`, `durationMs`
|
|
371
|
+
- `request:retry` — retrying after error. Fields: `method`, `attempt`, `delayMs`, `error`
|
|
372
|
+
- `request:error` — request failed. Fields: `method`, `error`
|
|
373
|
+
|
|
374
|
+
## Retry
|
|
375
|
+
|
|
376
|
+
Enabled by default (`retries: 1`). Only retries on transient errors (timeout, 5xx, network). Does NOT retry on 4xx or business errors. Exponential backoff: `retryDelayMs * 2^attempt`.
|
|
377
|
+
|
|
378
|
+
## QR Code URL
|
|
379
|
+
|
|
380
|
+
ARCA requires a QR code on printed invoices. `generateQRUrl` produces the official URL:
|
|
381
|
+
|
|
382
|
+
```typescript
|
|
383
|
+
const url = Arca.generateQRUrl({
|
|
384
|
+
fecha: "2026-03-28", // YYYY-MM-DD
|
|
385
|
+
cuit: 20123456789,
|
|
386
|
+
ptoVta: 1,
|
|
387
|
+
tipoCmp: CbteTipo.FACTURA_B,
|
|
388
|
+
nroCmp: 150,
|
|
389
|
+
importe: 121,
|
|
390
|
+
moneda: "PES",
|
|
391
|
+
ctz: 1,
|
|
392
|
+
tipoDocRec: DocTipo.CONSUMIDOR_FINAL,
|
|
393
|
+
nroDocRec: 0,
|
|
394
|
+
codAut: 73429843294823, // CAE number
|
|
395
|
+
});
|
|
396
|
+
// → "https://www.afip.gob.ar/fe/qr/?p=<base64>"
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
## WSFEX (Export invoices)
|
|
400
|
+
|
|
401
|
+
For export invoices (`Factura E`, `Nota de Crédito E`, etc.). Uses a separate ARCA web service (WSFEX) with different endpoints and schema.
|
|
402
|
+
|
|
403
|
+
```typescript
|
|
404
|
+
// Get next ID and number
|
|
405
|
+
const nextId = (await arca.ultimoIdExpo()) + 1;
|
|
406
|
+
const nextNum = await arca.siguienteComprobanteExpo(1, CbteTipo.FACTURA_E);
|
|
407
|
+
|
|
408
|
+
// Authorize export invoice
|
|
409
|
+
const result = await arca.crearFacturaExportacion({
|
|
410
|
+
Id: nextId,
|
|
411
|
+
Cbte_Tipo: CbteTipo.FACTURA_E,
|
|
412
|
+
Fecha_cbte: "20260328",
|
|
413
|
+
Punto_vta: 1,
|
|
414
|
+
Cbte_nro: nextNum,
|
|
415
|
+
Tipo_expo: 1, // 1=Bienes, 2=Servicios, 4=Otros
|
|
416
|
+
Permiso_existente: "N",
|
|
417
|
+
Dst_cmp: 203, // Country code (203 = USA)
|
|
418
|
+
Cliente: "ACME Corp",
|
|
419
|
+
Cuit_pais_cliente: 50000000016, // CUIT del país
|
|
420
|
+
Domicilio_cliente: "123 Main St, NY",
|
|
421
|
+
Id_impositivo: "12-3456789",
|
|
422
|
+
Moneda_Id: "DOL",
|
|
423
|
+
Moneda_ctz: 1200,
|
|
424
|
+
Idioma_cbte: 2, // 1=ES, 2=EN, 3=PT
|
|
425
|
+
Forma_pago: "Wire Transfer",
|
|
426
|
+
Incoterms: "FOB",
|
|
427
|
+
Items: [{
|
|
428
|
+
Pro_codigo: "SKU001",
|
|
429
|
+
Pro_ds: "Widget",
|
|
430
|
+
Pro_qty: 100,
|
|
431
|
+
Pro_umed: 7, // Unit of measure code
|
|
432
|
+
Pro_precio_uni: 10,
|
|
433
|
+
Pro_bonificacion: 0,
|
|
434
|
+
Pro_total_item: 1000,
|
|
435
|
+
}],
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
if (result.FEXResultAuth?.Resultado === "A") {
|
|
439
|
+
console.log("CAE:", result.FEXResultAuth.Cae);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
// Query methods
|
|
443
|
+
await arca.consultarComprobanteExpo(CbteTipo.FACTURA_E, 1, nextNum);
|
|
444
|
+
await arca.serverStatusExpo();
|
|
445
|
+
await arca.getPaisesExpo();
|
|
446
|
+
await arca.getIncotermsExpo();
|
|
447
|
+
await arca.getUMedExpo();
|
|
448
|
+
await arca.getTiposExpo();
|
|
449
|
+
await arca.getMonedasExpo();
|
|
450
|
+
await arca.getIdiomasExpo();
|
|
451
|
+
await arca.getCuitsPaisExpo();
|
|
452
|
+
await arca.getTiposCbteExpo();
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
## Key domain concepts
|
|
456
|
+
|
|
457
|
+
- **CUIT**: Argentine tax ID (11 digits, no hyphens). Used for business identification.
|
|
458
|
+
- **Punto de venta (PtoVta)**: Sales point number (1-99999). Must be pre-registered with ARCA.
|
|
459
|
+
- **CAE**: Código de Autorización Electrónica. Unique code ARCA returns for each approved invoice.
|
|
460
|
+
- **Comprobante**: Generic term for any fiscal document (factura, nota de crédito/débito, recibo).
|
|
461
|
+
- **WSFEv1**: ARCA's SOAP web service for electronic invoicing.
|
|
462
|
+
- **WSAA**: ARCA's authentication web service. Uses CMS/PKCS#7 signed tickets.
|
|
463
|
+
- **Homologación**: ARCA's testing/sandbox environment. Use `production: false`.
|
|
464
|
+
- **FCE MiPyME**: Factura de Crédito Electrónica for small/medium businesses. Requires CBU in opcionales.
|
|
465
|
+
- **Tipo C**: Invoices issued by monotributistas (simplified tax regime). No IVA discrimination.
|
|
466
|
+
- **WSFEX**: ARCA's web service for export invoices. Separate from WSFEv1, different schema.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ramiidv/arca-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "SDK para interactuar con los Web Services de ARCA (ex AFIP) - Facturación Electrónica Argentina",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
"files": [
|
|
15
15
|
"dist",
|
|
16
16
|
"README.md",
|
|
17
|
-
"LICENSE"
|
|
17
|
+
"LICENSE",
|
|
18
|
+
"llm.txt"
|
|
18
19
|
],
|
|
19
20
|
"scripts": {
|
|
20
21
|
"build": "tsc",
|
|
@@ -49,12 +50,12 @@
|
|
|
49
50
|
"node": ">=18.0.0"
|
|
50
51
|
},
|
|
51
52
|
"dependencies": {
|
|
52
|
-
"
|
|
53
|
-
"
|
|
53
|
+
"fast-xml-parser": "^5.5.9",
|
|
54
|
+
"node-forge": "^1.4.0"
|
|
54
55
|
},
|
|
55
56
|
"devDependencies": {
|
|
56
|
-
"@types/node": "^
|
|
57
|
-
"@types/node-forge": "^1.3.
|
|
58
|
-
"typescript": "^
|
|
57
|
+
"@types/node": "^25.5.0",
|
|
58
|
+
"@types/node-forge": "^1.3.14",
|
|
59
|
+
"typescript": "^6.0.2"
|
|
59
60
|
}
|
|
60
61
|
}
|