arca-sdk 0.5.0 → 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/CHANGELOG.md ADDED
@@ -0,0 +1,142 @@
1
+ # Changelog
2
+
3
+ Todos los cambios notables de este proyecto se documentan en este archivo.
4
+
5
+ ---
6
+
7
+ ## [1.0.0] — 2026-02-23
8
+
9
+ ### 🔴 Breaking Changes
10
+
11
+ Esta versión establece la API pública definitiva. **Requiere actualizar todos los imports** si venís de v0.x.
12
+
13
+ #### Métodos renombrados en WsfeService
14
+ | v0.x | v1.0.0 |
15
+ |-------|--------|
16
+ | `emitirTicketCSimple()` | `issueSimpleReceipt()` |
17
+ | `emitirTicketC()` | `issueReceipt()` |
18
+ | `emitirFacturaC()` | `issueInvoiceC()` |
19
+ | `emitirFacturaB()` | `issueInvoiceB()` |
20
+ | `emitirFacturaA()` | `issueInvoiceA()` |
21
+ | `emitirComprobante()` | *(privado — ya no accesible)* |
22
+
23
+ #### Método renombrado en PadronService
24
+ | v0.x | v1.0.0 |
25
+ |-------|--------|
26
+ | `getPersona(cuit)` | `getTaxpayer(cuit)` |
27
+
28
+ #### Configuración de WsfeService
29
+ | v0.x | v1.0.0 |
30
+ |-------|--------|
31
+ | `puntoVenta: 4` | `pointOfSale: 4` |
32
+
33
+ #### Tipos renombrados
34
+ | v0.x | v1.0.0 |
35
+ |-------|--------|
36
+ | `TipoComprobante` | `InvoiceType` |
37
+ | `TipoDocumento` | `TaxIdType` |
38
+ | `Concepto` | `BillingConcept` |
39
+ | `FacturaItem` | `InvoiceItem` |
40
+ | `Comprador` | `Buyer` |
41
+ | `EmitirFacturaRequest` | `IssueInvoiceRequest` |
42
+ | `Persona` | `Taxpayer` |
43
+ | `Domicilio` | `Address` |
44
+ | `Actividad` | `Activity` |
45
+ | `Impuesto` | `TaxRecord` |
46
+ | `PadronResponse` | `TaxpayerResponse` |
47
+ | `PadronConfig` | `TaxpayerServiceConfig` |
48
+
49
+ #### Fields renombrados en tipos
50
+ | Tipo | v0.x | v1.0.0 |
51
+ |------|-------|--------|
52
+ | `InvoiceItem` | `descripcion` | `description` |
53
+ | `InvoiceItem` | `cantidad` | `quantity` |
54
+ | `InvoiceItem` | `precioUnitario` | `unitPrice` |
55
+ | `InvoiceItem` | `alicuotaIva` | `vatRate` |
56
+ | `Buyer` | `tipoDocumento` | `docType` |
57
+ | `Buyer` | `nroDocumento` | `docNumber` |
58
+ | `CAEResponse` | `tipoComprobante` | `invoiceType` |
59
+ | `CAEResponse` | `puntoVenta` | `pointOfSale` |
60
+ | `CAEResponse` | `nroComprobante` | `invoiceNumber` |
61
+ | `CAEResponse` | `fecha` | `date` |
62
+ | `CAEResponse` | `vencimientoCae` | `caeExpiry` |
63
+ | `CAEResponse` | `resultado` | `result` |
64
+ | `CAEResponse` | `observaciones` | `observations` |
65
+ | `CAEResponse` | `iva` | `vat` |
66
+ | `CAEResponse` | `urlQr` | `qrUrl` |
67
+ | `ServiceStatus` | `AppServer` | `appServer` |
68
+ | `ServiceStatus` | `DbServer` | `dbServer` |
69
+ | `ServiceStatus` | `AuthServer` | `authServer` |
70
+ | `Taxpayer` | `idPersona` | `taxId` |
71
+ | `Taxpayer` | `tipoPersona` | `personType` |
72
+ | `Taxpayer` | `nombre` | `firstName` |
73
+ | `Taxpayer` | `apellido` | `lastName` |
74
+ | `Taxpayer` | `razonSocial` | `companyName` |
75
+ | `Taxpayer` | `estadoClave` | `status` |
76
+ | `Taxpayer` | `domicilio` | `addresses` |
77
+ | `Taxpayer` | `actividad` | `activities` |
78
+ | `Taxpayer` | `impuesto` | `taxes` |
79
+ | `Taxpayer` | `descripcionActividadPrincipal` | `mainActivity` |
80
+ | `Taxpayer` | `esInscriptoIVA` | `isVATRegistered` |
81
+ | `Taxpayer` | `esMonotributista` | `isMonotax` |
82
+ | `Taxpayer` | `esExento` | `isVATExempt` |
83
+ | `Address` | `direccion` | `street` |
84
+ | `Address` | `localidad` | `city` |
85
+ | `Address` | `codPostal` | `postalCode` |
86
+ | `Address` | `idProvincia` | `provinceId` |
87
+ | `Address` | `descripcionProvincia` | `province` |
88
+ | `Address` | `tipoDomicilio` | `type` |
89
+
90
+ #### Función renombrada en utils
91
+ | v0.x | v1.0.0 |
92
+ |-------|--------|
93
+ | `generarUrlQR()` | `generateQRUrl()` |
94
+
95
+ #### Enums — valores constantes renombrados
96
+ | Enum | v0.x | v1.0.0 |
97
+ |------|-------|--------|
98
+ | `TaxIdType` | `CONSUMIDOR_FINAL` | `FINAL_CONSUMER` |
99
+ | `TaxIdType` | `CI_EXTRANJERA` | `FOREIGN_ID` |
100
+ | `TaxIdType` | `CI_BUENOS_AIRES` | `BUENOS_AIRES_ID` |
101
+ | `TaxIdType` | `CI_POLICIA_FEDERAL` | `NATIONAL_POLICE_ID` |
102
+ | `BillingConcept` | `PRODUCTOS` | `PRODUCTS` |
103
+ | `BillingConcept` | `SERVICIOS` | `SERVICES` |
104
+ | `BillingConcept` | `PRODUCTOS_Y_SERVICIOS` | `PRODUCTS_AND_SERVICES` |
105
+
106
+ ---
107
+
108
+ ### ✅ Nuevas funcionalidades
109
+
110
+ - **`WsfeService.getInvoice(type, number)`**: Consulta un comprobante ya emitido (FECompConsultar).
111
+ - **`WsfeService.getPointsOfSale()`**: Lista los puntos de venta habilitados (FEParamGetPtosVenta).
112
+ - **`ArcaNetworkError`**: Ahora exportado públicamente para manejo de errores de red.
113
+ - **`InvoiceDetails`**: Nuevo tipo para la respuesta de `getInvoice()`.
114
+ - **`PointOfSale`**: Nuevo tipo para la respuesta de `getPointsOfSale()`.
115
+
116
+ ### 🐛 Fixes
117
+
118
+ - `ServiceStatus` ahora tiene campos `camelCase` (`appServer`, `dbServer`, `authServer`) en lugar de `PascalCase`.
119
+ - `emitirComprobante` (ahora `issueDocument`) se volvió privado — ya no es accesible desde fuera del servicio.
120
+ - Diccionario de hints de errores (`ARCA_ERROR_HINTS`) expandido a 15+ códigos documentados.
121
+ - Eliminado `WsaaResponse` (tipo sin uso).
122
+ - Tipado explícito en `PadronService`: eliminados todos los `any` en métodos privados.
123
+
124
+ ### 🧪 Tests
125
+
126
+ - Nuevo suite de tests para `WsfeService` (`wsfe.test.ts`).
127
+ - Tests existentes actualizados a la nueva API.
128
+
129
+ ---
130
+
131
+ ## [0.5.0] — 2026-02-22
132
+
133
+ - Agregado Padrón A13 service (`PadronService`)
134
+ - `ArcaError` con campo `hint` para guiar al desarrollador
135
+ - `checkStatus()` con default seguro en `homologacion`
136
+
137
+ ## [0.4.0] — 2026-02-21
138
+
139
+ - Primera versión pública del SDK
140
+ - `WsaaService` con cache en memoria + persistencia opcional
141
+ - `WsfeService` con Ticket C, Factura A, B, C
142
+ - Generador de QR oficial de ARCA
package/README.md CHANGED
@@ -3,13 +3,13 @@
3
3
  **La SDK moderna de ARCA (ex-AFIP) que no te rompe las bolas.**
4
4
 
5
5
  SDK en TypeScript para integración con servicios de ARCA:
6
- - ✅ **Type-safe**: TypeScript strict mode
7
- - ✅ **Simple**: No más XML manual
8
- - ✅ **Automático**: Cache de tokens, persistencia opcional (God Mode)
9
- - ✅ **Fiscal**: Generador de QR oficial ARCA/AFIP ultra-robusto
6
+ - ✅ **Type-safe**: TypeScript strict mode, 100% tipado
7
+ - ✅ **Simple**: API en inglés, sin XML manual, sin magia negra
8
+ - ✅ **Automático**: Cache de tokens + persistencia opcional (God Mode)
9
+ - ✅ **Fiscal**: Generador de QR oficial de ARCA ultra-robusto
10
10
  - ✅ **Padrón**: Consulta de CUIT (A13) para autocompletado de datos
11
11
  - ✅ **Resiliente**: Maneja errores SSL ("dh key too small") y timeouts
12
- - ✅ **Moderno**: ESM + CJS nativo, Node.js 18+
12
+ - ✅ **Moderno**: ESM + CJS nativo, Node.js 18+, Bun compatible
13
13
 
14
14
  ---
15
15
 
@@ -25,35 +25,46 @@ bun add arca-sdk
25
25
  ## ⚡ Quick Start
26
26
  ```typescript
27
27
  import { WsaaService, WsfeService } from 'arca-sdk';
28
+ import * as fs from 'fs';
28
29
 
29
- // 1. Configuración base
30
- const config = {
30
+ // 1. Autenticar con WSAA
31
+ const wsaa = new WsaaService({
32
+ environment: 'homologacion',
33
+ cuit: '20123456789',
34
+ cert: fs.readFileSync('cert.pem', 'utf-8'),
35
+ key: fs.readFileSync('key.pem', 'utf-8'),
36
+ service: 'wsfe',
37
+ });
38
+
39
+ const ticket = await wsaa.login();
40
+
41
+ // 2. Crear servicio de facturación
42
+ const wsfe = new WsfeService({
31
43
  environment: 'homologacion',
32
44
  cuit: '20123456789',
33
- cert: '...certificado PEM...',
34
- key: '...clave privada PEM...',
35
- };
45
+ ticket,
46
+ pointOfSale: 4,
47
+ });
36
48
 
37
- // 2. Emitir un Ticket C en dos líneas
38
- const wsfe = new WsfeService(config);
39
- const result = await wsfe.emitirTicketCSimple({ total: 1500 });
49
+ // 3. Emitir un Ticket C
50
+ const result = await wsfe.issueSimpleReceipt({ total: 1500 });
40
51
 
41
52
  console.log('CAE:', result.cae);
42
- console.log('QR URL:', result.urlQr); // ← Ya viene integrado!
53
+ console.log('QR URL:', result.qrUrl); // ← Ya viene integrado!
43
54
  ```
44
55
 
45
56
  ---
46
57
 
47
58
  ## 👑 God Mode: Persistencia Automática
48
- No manejes tickets manualmente. Pasale un `storage` al SDK y se encargará de guardar, recuperar y renovar el token solo cuando expire.
59
+ No manejes tokens manualmente. Pasale un `storage` al SDK y se encargará de guardar, recuperar y renovar el TA solo cuando expire.
49
60
 
50
61
  ```typescript
51
62
  const wsaa = new WsaaService({
52
63
  ...config,
53
64
  service: 'wsfe',
54
65
  storage: {
55
- get: async (key) => await db.token.findUnique({ where: { key } }),
56
- save: async (key, data) => await db.token.upsert({ ... }),
66
+ get: async (cuit, env) => await db.token.findUnique({ where: { cuit, env } }),
67
+ save: async (cuit, env, ticket) => await db.token.upsert({ ... }),
57
68
  }
58
69
  });
59
70
 
@@ -64,55 +75,107 @@ const ticket = await wsaa.login();
64
75
  ---
65
76
 
66
77
  ## 🔍 Consulta de Padrón (A13)
67
- Obtené los datos de un cliente (Nombre, Domicilio, IVA) solo con su CUIT. Ideal para POS.
78
+ Obtené los datos de un contribuyente (nombre, domicilio, condición IVA) solo con su CUIT.
68
79
 
69
80
  ```typescript
70
81
  import { PadronService } from 'arca-sdk';
71
82
 
72
83
  const padron = new PadronService(config);
73
- const { persona, error } = await padron.getPersona('30111111118');
74
-
75
- if (persona) {
76
- console.log('Razón Social:', persona.razonSocial || `${persona.nombre} ${persona.apellido}`);
77
- console.log('Provincia:', persona.domicilio[0].descripcionProvincia);
78
- console.log('¿Es Inscripto?:', persona.esInscriptoIVA);
84
+ const { taxpayer, error } = await padron.getTaxpayer('30111111118');
85
+
86
+ if (taxpayer) {
87
+ const name = taxpayer.companyName || `${taxpayer.firstName} ${taxpayer.lastName}`;
88
+ console.log('Nombre:', name);
89
+ console.log('Provincia:', taxpayer.addresses[0].province);
90
+ console.log('¿Inscripto IVA?:', taxpayer.isVATRegistered);
91
+ console.log('¿Monotributista?:', taxpayer.isMonotax);
79
92
  }
80
93
  ```
81
94
 
82
95
  ---
83
96
 
84
- ## 📱 Generador de QR Oficial
85
- AFIP exige que los comprobantes impresos tengan un código QR. El SDK lo genera cumpliendo estrictamente con el formato oficial (JSON ordenado, Base64 URL-safe, etc).
97
+ ## 📱 Comprobantes soportados
86
98
 
87
99
  ```typescript
88
- // 1. Integrado en WsfeService (Recomendado)
89
- const result = await wsfe.emitirTicketCSimple({ total: 1500 });
90
- console.log(result.urlQr);
100
+ // Ticket C Consumidor Final (solo total)
101
+ const cae = await wsfe.issueSimpleReceipt({ total: 1500 });
102
+
103
+ // Ticket C — con detalle de items (los items se guardan localmente, no van a ARCA)
104
+ const cae = await wsfe.issueReceipt({
105
+ items: [
106
+ { description: 'Café con leche', quantity: 2, unitPrice: 750 },
107
+ { description: 'Medialunas x3', quantity: 1, unitPrice: 500 },
108
+ ],
109
+ });
110
+
111
+ // Factura C — Consumidor Final con items
112
+ const cae = await wsfe.issueInvoiceC({ items: [...] });
91
113
 
92
- // 2. O manual si lo necesitás por separado
93
- import { generarUrlQR } from 'arca-sdk';
94
- const urlQr = generarUrlQR(caeResponse, '20123456789', 1500);
114
+ // Factura B con IVA discriminado (requiere vatRate en cada item)
115
+ const cae = await wsfe.issueInvoiceB({
116
+ items: [
117
+ { description: 'Servicio de diseño', quantity: 10, unitPrice: 1000, vatRate: 21 },
118
+ ],
119
+ buyer: { docType: TaxIdType.CUIT, docNumber: '20987654321' },
120
+ });
121
+
122
+ // Factura A — entre Responsables Inscriptos
123
+ const cae = await wsfe.issueInvoiceA({
124
+ items: [...],
125
+ buyer: { docType: TaxIdType.CUIT, docNumber: '30123456789' },
126
+ });
95
127
  ```
96
128
 
97
129
  ---
98
130
 
99
- ## 🖨️ Generación de PDF
100
- Para mantener la SDK ligera, no incluimos generadores de PDF (como `jspdf`) en el core.
101
- **Tip:** La URL del QR (`urlQr`) apunta a la vista oficial de ARCA que ya es 100% imprimible y legal. Si necesitás PDF local, podés usar los datos de `CAEResponse` con tu librería favorita.
131
+ ## 🔎 Consultar un comprobante ya emitido
132
+
133
+ ```typescript
134
+ const invoice = await wsfe.getInvoice(InvoiceType.TICKET_C, 42);
135
+ console.log('Total:', invoice.total);
136
+ console.log('CAE:', invoice.cae);
137
+ ```
102
138
 
103
139
  ---
104
140
 
105
- ## 🩺 Chequeo de Salud
106
- Verificá si los servidores de ARCA están online antes de intentar facturar.
141
+ ## 🏪 Listar puntos de venta
107
142
 
108
143
  ```typescript
109
- const status = await wsfe.checkStatus();
110
- console.log('AppServer:', status.appServer); // 'OK'
144
+ const points = await wsfe.getPointsOfSale();
145
+ points.forEach(p => {
146
+ console.log(`PdV ${p.number}: ${p.type} — ${p.isBlocked ? '🔴 Bloqueado' : '✅ Activo'}`);
147
+ });
111
148
  ```
112
149
 
113
150
  ---
114
151
 
115
- ## 📝 Servicios y Comprobantes
152
+ ## 📱 QR Oficial de ARCA
153
+
154
+ ```typescript
155
+ // 1. Integrado automáticamente en todos los métodos de emisión
156
+ const result = await wsfe.issueSimpleReceipt({ total: 1500 });
157
+ console.log(result.qrUrl);
158
+
159
+ // 2. O generalo manualmente
160
+ import { generateQRUrl } from 'arca-sdk';
161
+ const url = generateQRUrl(caeResponse, '20123456789', 1500);
162
+ ```
163
+
164
+ ---
165
+
166
+ ## 🩺 Estado de los servidores
167
+
168
+ ```typescript
169
+ // Sin necesidad de autenticación
170
+ const status = await WsfeService.checkStatus('produccion');
171
+ console.log('AppServer:', status.appServer); // 'OK'
172
+ console.log('DbServer:', status.dbServer);
173
+ console.log('AuthServer:', status.authServer);
174
+ ```
175
+
176
+ ---
177
+
178
+ ## 📝 Referencia de Servicios
116
179
 
117
180
  | Clase | Servicio ARCA | Descripción |
118
181
  |-------|---------------|-------------|
@@ -120,23 +183,37 @@ console.log('AppServer:', status.appServer); // 'OK'
120
183
  | `WsfeService` | `wsfev1` | Facturación Electrónica (A, B, C) |
121
184
  | `PadronService` | `ws_sr_padron_a13` | Consulta de datos de contribuyentes |
122
185
 
123
- ### Comprobantes soportados en `WsfeService`:
124
- - `emitirTicketCSimple()`: Rápido para Consumidor Final.
125
- - `emitirTicketC()`: Con detalle de items.
126
- - `emitirFacturaB()`: Para Responsables Inscriptos o Facturas > $ limite.
127
- - `emitirFacturaA()`: Con discriminación de IVA.
186
+ ### Enums disponibles
187
+
188
+ ```typescript
189
+ import { InvoiceType, BillingConcept, TaxIdType } from 'arca-sdk';
190
+
191
+ InvoiceType.FACTURA_A // 1
192
+ InvoiceType.FACTURA_B // 6
193
+ InvoiceType.FACTURA_C // 11
194
+ InvoiceType.TICKET_C // 83
195
+
196
+ BillingConcept.PRODUCTS // 1
197
+ BillingConcept.SERVICES // 2
198
+ BillingConcept.PRODUCTS_AND_SERVICES // 3
199
+
200
+ TaxIdType.CUIT // 80
201
+ TaxIdType.DNI // 96
202
+ TaxIdType.FINAL_CONSUMER // 99
203
+ ```
128
204
 
129
205
  ---
130
206
 
131
207
  ## 🛠️ Desarrollo y Tests
208
+
132
209
  ```bash
133
- # Correr tests con mocks de ARCA
210
+ # Correr tests (unit + mocks de ARCA)
134
211
  bun test
135
212
 
136
- # Verificar tipos
213
+ # Verificar tipos TypeScript
137
214
  bun run lint
138
215
 
139
- # Build para producción (CJS + ESM)
216
+ # Build para producción (CJS + ESM + .d.ts)
140
217
  bun run build
141
218
  ```
142
219