keycae-ts 1.0.0 β†’ 1.2.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 KeyCAE Software S.A.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,96 +1,199 @@
1
1
  # keycae-ts πŸš€
2
2
 
3
- Cliente SDK oficial en **TypeScript** y **JavaScript** para interactuar con la plataforma de **KeyCAE.ar** y emitir facturaciΓ³n electrΓ³nica oficial homologada ante **ARCA (ex AFIP)** de forma simple y resiliente.
3
+ [![npm version](https://img.shields.io/npm/v/keycae-ts.svg)](https://www.npmjs.com/package/keycae-ts)
4
+ [![npm downloads](https://img.shields.io/npm/dm/keycae-ts.svg)](https://www.npmjs.com/package/keycae-ts)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
4
6
 
5
- ## InstalaciΓ³n
7
+ Cliente SDK oficial en **TypeScript** y **JavaScript** para interactuar con **KeyCAE.ar** y emitir facturaciΓ³n electrΓ³nica oficial ante **ARCA (ex AFIP)**.
6
8
 
7
- Instala el SDK en tu proyecto Node.js/TypeScript:
9
+ ## InstalaciΓ³n
8
10
 
9
11
  ```bash
10
12
  npm install keycae-ts
11
- # O usando yarn / pnpm
12
- yarn add keycae-ts
13
- pnpm add keycae-ts
14
13
  ```
15
14
 
16
- ## Inicio RÑpido (Modelo A: Delegación Directa ⭐)
15
+ ## Inicio RΓ‘pido
16
+
17
+ El SDK soporta tanto el **Sandbox PΓΊblico** (sin cuenta, ideal para desarrollo rΓ‘pido) como el entorno de **ProducciΓ³n** (con cuenta registrada):
17
18
 
18
- Esta es la forma recomendada por defecto. En minutos podΓ©s facturar sin lidiar con llaves privadas o subir archivos de certificados.
19
+ * **Para Probar en Sandbox (Sin Cuenta):** Usa la clave pΓΊblica `sk_test_public_sandbox_cuit_20999999999` y el CUIT de pruebas `20999999999`.
20
+ * **Para ProducciΓ³n (Con Cuenta):** RegΓ­strate en [keycae.ar](https://keycae.ar) para obtener tu API Key `sk_live_...` y configura tu CUIT real.
19
21
 
20
22
  ```typescript
21
23
  import { KeyCaeClient } from 'keycae-ts';
22
24
 
23
- // 1. Inicializar el cliente con tu API Key
24
- const client = new KeyCaeClient('sk_test_tu_api_key_aqui');
25
-
26
- async function main() {
27
- try {
28
- // 2. Registrar la delegaciΓ³n (previamente debΓ©s adherir el servicio en el portal de ARCA al CUIT representante 20254459306)
29
- console.log('Iniciando delegaciΓ³n directa...');
30
- const delegation = await client.createDelegation({
31
- cuit: '20254459306',
32
- organization: 'Digital Media S.A.'
33
- });
34
-
35
- console.log(`Estado inicial de delegaciΓ³n: ${delegation.status}`);
36
-
37
- // 3. Emitir una factura electrΓ³nica homologada (con CAE y PDF)
38
- console.log('Emitiendo factura fiscal...');
39
- const invoice = await client.emitInvoice({
40
- cuit_emisor: '20254459306',
41
- punto_de_venta: 1,
42
- tipo_comprobante: 'C',
43
- receptor: {
44
- tipo_doc: 'DNI',
45
- nro_doc: '35987654'
46
- },
47
- conceptos: [
48
- {
49
- descripcion: 'Servicios de ConsultorΓ­a de Software',
50
- precio: 150000.00
51
- }
52
- ]
53
- }, 'idempotency_key_factura_42'); // Idempotency key para prevenir duplicaciones de red
54
-
55
- console.log('Β‘Factura autorizada exitosamente!');
56
- console.log(`Comprobante: Nro. ${invoice.numero_factura}`);
57
- console.log(`CAE Otorgado: ${invoice.cae}`);
58
- console.log(`Vencimiento CAE: ${invoice.cae_vencimiento}`);
59
- console.log(`PDF de ImpresiΓ³n: ${invoice.url_pdf}`);
60
- console.log(`CΓ³digo QR Fiscal: ${invoice.url_qr}`);
61
-
62
- } catch (error) {
63
- console.error('Error durante la operaciΓ³n:', error);
64
- }
65
- }
66
-
67
- main();
25
+ // Ejemplo para Sandbox PΓΊblico:
26
+ const client = new KeyCaeClient('sk_test_public_sandbox_cuit_20999999999');
27
+ // O para producciΓ³n: const client = new KeyCaeClient('sk_live_tu_api_key');
28
+
29
+ // Consultar contribuyente
30
+ const taxpayer = await client.getTaxpayer('20254459306');
31
+ console.log(`${taxpayer.nombre} | ${taxpayer.estado}`);
32
+
33
+ // Verificar quΓ© tipos de factura puede emitir
34
+ const capability = await client.checkEmissionCapability('20254459306');
35
+ console.log(`Tipos compatibles: ${capability.compatible_types.join(', ')}`);
36
+ console.log(capability.recommendation);
37
+
38
+ // Emitir factura
39
+ const invoice = await client.emitInvoice({
40
+ cuit_emisor: '20254459306',
41
+ punto_de_venta: 1,
42
+ tipo_comprobante: 'B',
43
+ receptor: { tipo_doc: 'CUIT', nro_doc: '20333444555' },
44
+ conceptos: [{ descripcion: 'Servicios', precio: 15000 }]
45
+ }, 'idempotency_key_42');
46
+
47
+ console.log(`CAE: ${invoice.cae}`);
48
+ console.log(`PDF: ${invoice.url_pdf}`);
68
49
  ```
69
50
 
70
- ## Notificaciones en Tiempo Real (Telegram Alerts)
51
+ ### Precios netos (sin IVA)
71
52
 
72
- ConfigurΓ‘ tu bot de Telegram a travΓ©s de la API para recibir alertas mΓ³viles al instante de cada comprobante emitido:
53
+ Por defecto `conceptos[].precio` se envΓ­a con IVA incluido. Si tu sistema maneja precios netos, pasΓ‘ `iva_incluido: false` y KeyCAE calcula el IVA automΓ‘ticamente:
73
54
 
74
55
  ```typescript
75
- import { KeyCaeClient } from 'keycae-ts';
56
+ const invoice = await client.emitInvoice({
57
+ cuit_emisor: '20254459306',
58
+ punto_de_venta: 1,
59
+ tipo_comprobante: 'A',
60
+ iva_incluido: false, // conceptos[].precio son netos
61
+ receptor: { tipo_doc: 'CUIT', nro_doc: '30999888776' },
62
+ conceptos: [{ descripcion: 'Servicio profesional', precio: 1000, alicuota_iva: 21 }]
63
+ }, 'idempotency_key_43');
64
+ // β†’ Neto $1.000 | IVA 21% $210 | Total $1.210
65
+ ```
66
+
67
+ ## Modelos de ConexiΓ³n
68
+
69
+ ### Modalidad A: DelegaciΓ³n Directa (Recomendada)
70
+ Sin certificados, sin llaves privadas. En minutos facturΓ‘s.
71
+
72
+ ```typescript
73
+ const delegation = await client.createDelegation({
74
+ cuit: '20254459306',
75
+ organization: 'Tu Empresa'
76
+ });
77
+ ```
78
+
79
+ ### Modalidad B: BΓ³vedas KMS
80
+ GeneraciΓ³n segura de claves RSA y CSR.
76
81
 
77
- const client = new KeyCaeClient('sk_test_tu_api_key_aqui');
78
-
79
- async function setupAlerts() {
80
- // Guardar configuraciΓ³n del Bot
81
- await client.saveTelegramSettings({
82
- telegram_bot_token: '123456789:ABCdefGhIjKlMnOpQrStUvWxYz_TOKEN',
83
- telegram_chat_id: '987654321'
84
- });
85
-
86
- // Consultar configuraciΓ³n actual (retorna enmascarada)
87
- const settings = await client.getTelegramSettings();
88
- console.log('Ajustes de alertas activos:', settings);
89
- }
90
-
91
- setupAlerts();
82
+ ```typescript
83
+ const credential = await client.createCredential({
84
+ cuit: '20254459306',
85
+ organization: 'Tu Empresa'
86
+ });
87
+ ```
88
+
89
+ ### Modalidad C: Importar Certificado
90
+ Subida directa de certificados (.crt) y llaves (.key).
91
+
92
+ ```typescript
93
+ await client.importCredential({
94
+ cuit: '20254459306',
95
+ organization: 'Tu Empresa',
96
+ certificate: certificatePem,
97
+ private_key: privateKeyPem
98
+ });
92
99
  ```
93
100
 
101
+ ## MΓ©todos Disponibles
102
+
103
+ ### Taxpayers
104
+ | MΓ©todo | DescripciΓ³n |
105
+ |--------|-------------|
106
+ | `getTaxpayer(cuit)` | Consultar contribuyente en padrΓ³n ARCA |
107
+ | `checkEmissionCapability(cuit)` | Verificar tipos de factura compatibles |
108
+
109
+ ### Delegations
110
+ | MΓ©todo | DescripciΓ³n |
111
+ |--------|-------------|
112
+ | `createDelegation(data)` | Iniciar delegaciΓ³n directa |
113
+ | `checkDelegationStatus()` | Consultar estado de delegaciΓ³n |
114
+
115
+ ### Credentials (KMS)
116
+ | MΓ©todo | DescripciΓ³n |
117
+ |--------|-------------|
118
+ | `createCredential(data)` | Generar RSA keypair + CSR |
119
+ | `listCredentials()` | Listar certificados registrados |
120
+ | `importCredential(data)` | Importar certificado existente |
121
+ | `activateCredential(id, cert)` | Activar bΓ³veda con certificado ARCA |
122
+ | `deleteCredential(id)` | Eliminar bΓ³veda de claves |
123
+
124
+ ### Invoices
125
+ | MΓ©todo | DescripciΓ³n |
126
+ |--------|-------------|
127
+ | `emitInvoice(data, idempotencyKey?)` | Emitir factura electrΓ³nica (CAE) |
128
+ | `getInvoice(id)` | Obtener detalles de factura |
129
+ | `listInvoices(limit?, offset?)` | Listar facturas recientes |
130
+ | `getInvoicePdfBuffer(id)` | Descargar PDF de factura |
131
+
132
+ ### Puntos de Venta
133
+ | MΓ©todo | DescripciΓ³n |
134
+ |--------|-------------|
135
+ | `listPuntosDeVenta()` | Listar puntos de venta habilitados |
136
+
137
+ ### Billing & Settings
138
+ | MΓ©todo | DescripciΓ³n |
139
+ |--------|-------------|
140
+ | `getBillingStatus()` | Estado del plan y consumo |
141
+ | `getTelegramSettings()` | Obtener configuraciΓ³n Telegram |
142
+ | `saveTelegramSettings(data)` | Guardar configuraciΓ³n Telegram |
143
+ | `health()` | Health check de la API |
144
+
145
+ ### Partners (ERPs / SaaS)
146
+ | MΓ©todo | DescripciΓ³n |
147
+ |--------|-------------|
148
+ | `createPartnerSubaccount(data)` | Crear subcuenta completa para un cliente final (usuario + API Key) |
149
+ | `listPartnerSubaccounts()` | Listar tus clientes con plan y consumo mensual |
150
+ | `preauthorizeCuit(cuit)` | Pre-autorizar un CUIT para facturaciΓ³n consolidada |
151
+ | `getPartnerConfig(partnerId)` | ConfiguraciΓ³n pΓΊblica de co-branding (sin auth) |
152
+
153
+ > Los mΓ©todos de Partners requieren instanciar el cliente con tu **API Key de Partner** (`sk_partner_live_...`) y solo deben usarse desde tu backend:
154
+ >
155
+ > ```typescript
156
+ > const partnerClient = new KeyCaeClient('sk_partner_live_mi-erp_...');
157
+ >
158
+ > const sub = await partnerClient.createPartnerSubaccount({
159
+ > cuit: '20304567891',
160
+ > organization: 'Cliente S.A.',
161
+ > email: 'cliente@empresa.com'
162
+ > });
163
+ > // sub.api_key y sub.password se devuelven UNA sola vez
164
+ >
165
+ > const { clients, total } = await partnerClient.listPartnerSubaccounts();
166
+ > ```
167
+ >
168
+ > πŸ“– GuΓ­a completa del programa de partners: [keycae.ar/docs/partners.md](https://keycae.ar/docs/partners.md)
169
+
170
+ ## Tipos de Comprobante
171
+
172
+ | Tipo | DescripciΓ³n |
173
+ |------|-------------|
174
+ | `A` | IVA discriminado (Responsable Inscripto β†’ RI) |
175
+ | `B` | Consumidor Final (RI β†’ CF) |
176
+ | `C` | Exento (Monotributo / Exento) |
177
+ | `M` | Monotributo |
178
+ | `E` | ExportaciΓ³n |
179
+ | `NCA` `NCB` `NCC` `NCE` `NCM` | Notas de CrΓ©dito (A, B, C, E, M) |
180
+ | `NDA` `NDB` `NDC` `NDE` `NDM` | Notas de DΓ©bito (A, B, C, E, M) |
181
+
182
+ ## Alertas Telegram
183
+
184
+ ```typescript
185
+ await client.saveTelegramSettings({
186
+ telegram_bot_token: '123456:***',
187
+ telegram_chat_id: '987654321'
188
+ });
189
+ ```
190
+
191
+ ## DocumentaciΓ³n
192
+
193
+ - πŸ“– [docs.keycae.ar](https://docs.keycae.ar) β€” DocumentaciΓ³n interactiva
194
+ - πŸ“„ [llms.txt](https://keycae.ar/llms.txt) β€” Para AI agents
195
+ - πŸ”Œ [MCP Server](https://www.npmjs.com/package/keycae-mcp) β€” Para Cursor/Claude
196
+
94
197
  ## Licencia
95
198
 
96
199
  MIT
package/dist/index.d.ts CHANGED
@@ -1,3 +1,9 @@
1
+ export interface DomicilioFiscal {
2
+ direccion: string | null;
3
+ localidad: string | null;
4
+ cod_postal: string | null;
5
+ provincia: string | null;
6
+ }
1
7
  export interface TaxpayerResponse {
2
8
  cuit: string;
3
9
  nombre: string;
@@ -5,23 +11,70 @@ export interface TaxpayerResponse {
5
11
  categoria_monotributo?: string;
6
12
  es_iva_inscripto: boolean;
7
13
  estado: string;
14
+ condicion_iva?: string;
15
+ actividades?: string[];
16
+ domicilio_fiscal?: DomicilioFiscal;
8
17
  }
9
18
  export interface InvoiceReceptor {
10
- tipo_doc: 'DNI' | 'CUIT' | 'CUIL' | 'PASAPORTE';
19
+ tipo_doc: 'DNI' | 'CUIT' | 'CUIL' | 'PASAPORTE' | 'SIN_IDENTIFICAR';
11
20
  nro_doc: string;
21
+ razon_social?: string;
22
+ condicion_iva?: string;
12
23
  }
13
24
  export interface InvoiceItem {
14
25
  descripcion: string;
15
26
  precio: number;
27
+ cantidad?: number;
28
+ alicuota_iva?: number;
29
+ }
30
+ export interface Tributo {
31
+ id: number;
32
+ descripcion: string;
33
+ base_imponible: number;
34
+ alicuota: number;
35
+ importe: number;
36
+ }
37
+ export interface Opcional {
38
+ id: string;
39
+ valor: string;
40
+ }
41
+ export interface CondicionesIvaResponse {
42
+ condiciones: {
43
+ codigo: number;
44
+ nombre: string;
45
+ }[];
16
46
  }
17
47
  export interface InvoiceInput {
18
48
  cuit_emisor: string;
19
49
  punto_de_venta: number;
20
- tipo_comprobante: 'A' | 'B' | 'C' | 'M';
50
+ tipo_comprobante: 'A' | 'B' | 'C' | 'M' | 'E' | 'NCA' | 'NCB' | 'NCC' | 'NCE' | 'NCM' | 'NDA' | 'NDB' | 'NDC' | 'NDE' | 'NDM' | 'FCE_A' | 'FCE_B' | 'FCE_C' | 'FCE_NDA' | 'FCE_NDB' | 'FCE_NDC' | 'FCE_NCA' | 'FCE_NCB' | 'FCE_NCC';
21
51
  receptor: InvoiceReceptor;
22
52
  conceptos: InvoiceItem[];
53
+ /**
54
+ * Default `true`: los `conceptos[].precio` se envΓ­an con IVA incluido (precio final).
55
+ * Con `false`, los precios se interpretan como netos (sin IVA) y KeyCAE calcula
56
+ * y adiciona el IVA segΓΊn la `alicuota_iva` de cada Γ­tem.
57
+ * Sin efecto en comprobantes sin discriminaciΓ³n de IVA (tipo C / E).
58
+ */
59
+ iva_incluido?: boolean;
60
+ tributos?: Tributo[];
61
+ moneda?: string;
62
+ moneda_cotizacion?: number;
63
+ fecha_comprobante?: string;
64
+ fecha_servicio_desde?: string;
65
+ fecha_servicio_hasta?: string;
66
+ fecha_vto_pago?: string;
67
+ condicion_iva_receptor?: number;
68
+ opcionales?: Opcional[];
23
69
  brand_logo_url?: string;
24
70
  brand_color?: string;
71
+ cbtes_asociados?: {
72
+ tipo: string | number;
73
+ punto_de_venta: number;
74
+ numero: number;
75
+ cuit?: string;
76
+ fecha?: string;
77
+ }[];
25
78
  }
26
79
  export interface InvoiceResponse {
27
80
  id: string;
@@ -61,7 +114,7 @@ export interface DelegationInput {
61
114
  }
62
115
  export interface DelegationResponse {
63
116
  id: string;
64
- status: 'pending' | 'accepted' | 'rejected';
117
+ status: 'pending' | 'accepted' | 'rejected' | 'pending_auto';
65
118
  cuit: string;
66
119
  organization: string;
67
120
  representativeCuit: string;
@@ -89,6 +142,70 @@ export interface KmsImportInput {
89
142
  certificate: string;
90
143
  private_key: string;
91
144
  }
145
+ export interface PuntoDeVenta {
146
+ numero: number;
147
+ tipoEmision: string;
148
+ tipoAutomatizacion?: string;
149
+ fechaServicioDesde?: string;
150
+ fechaServicioHasta?: string;
151
+ }
152
+ export interface EmissionCapability {
153
+ cuit: string;
154
+ condicion_iva: string;
155
+ compatible_types: string[];
156
+ recommendation: string;
157
+ tip: string;
158
+ }
159
+ export interface HealthResponse {
160
+ status: string;
161
+ version?: string;
162
+ uptime?: number;
163
+ }
164
+ export interface PartnerSubaccountInput {
165
+ /** CUIT fiscal del cliente final (11 dΓ­gitos, sin guiones) */
166
+ cuit: string;
167
+ /** RazΓ³n social del cliente final */
168
+ organization: string;
169
+ /** Email de acceso del cliente final */
170
+ email: string;
171
+ }
172
+ export interface PartnerSubaccountResponse {
173
+ id: string;
174
+ cuit: string;
175
+ organization: string;
176
+ email: string;
177
+ /** ContraseΓ±a generada β€” se devuelve UNA sola vez. Entregar por canal seguro. */
178
+ password: string;
179
+ /** API Key live de la subcuenta β€” se devuelve UNA sola vez. */
180
+ api_key: string;
181
+ partner_id: string;
182
+ }
183
+ export interface PartnerClient {
184
+ cuit: string;
185
+ organization: string;
186
+ email: string;
187
+ plan: 'free' | 'developer' | 'platform';
188
+ invoices_this_month: number;
189
+ created_at: string | null;
190
+ }
191
+ export interface PartnerClientsResponse {
192
+ partner_id: string;
193
+ total: number;
194
+ clients: PartnerClient[];
195
+ }
196
+ export interface PartnerPreauthResponse {
197
+ success: boolean;
198
+ message: string;
199
+ partner_id: string;
200
+ cuit: string;
201
+ }
202
+ export interface PartnerPublicConfig {
203
+ id: string;
204
+ name: string;
205
+ logo_url: string;
206
+ brand_color: string;
207
+ billing_mode: 'decentralized' | 'consolidated';
208
+ }
92
209
  export declare class KeyCaeClient {
93
210
  private apiKey;
94
211
  private baseUrl;
@@ -98,6 +215,10 @@ export declare class KeyCaeClient {
98
215
  * Consultar Contribuyente en PadrΓ³n ARCA
99
216
  */
100
217
  getTaxpayer(cuit: string): Promise<TaxpayerResponse>;
218
+ /**
219
+ * Verificar quΓ© tipos de factura puede emitir un CUIT segΓΊn su condiciΓ³n fiscal
220
+ */
221
+ checkEmissionCapability(cuit: string): Promise<EmissionCapability>;
101
222
  /**
102
223
  * Registrar / Iniciar Direct Delegation
103
224
  */
@@ -110,6 +231,10 @@ export declare class KeyCaeClient {
110
231
  * Crear BΓ³veda de Claves KMS & Generar CSR
111
232
  */
112
233
  createCredential(data: KmsCredentialInput): Promise<KmsCredentialResponse>;
234
+ /**
235
+ * Listar Credenciales Digitales Registradas
236
+ */
237
+ listCredentials(): Promise<KmsCredentialResponse[]>;
113
238
  /**
114
239
  * Importar Credenciales de Firma Existentes (.key y .crt)
115
240
  */
@@ -126,10 +251,27 @@ export declare class KeyCaeClient {
126
251
  * Emitir Factura ElectrΓ³nica Homologada (CAE)
127
252
  */
128
253
  emitInvoice(data: InvoiceInput, idempotencyKey?: string): Promise<InvoiceResponse>;
254
+ /**
255
+ * Obtener Detalles de una Factura por ID
256
+ */
257
+ getInvoice(id: string): Promise<InvoiceResponse>;
258
+ /**
259
+ * Listar Facturas Recientes
260
+ */
261
+ listInvoices(limit?: number, offset?: number): Promise<{
262
+ invoices: InvoiceResponse[];
263
+ total: number;
264
+ }>;
129
265
  /**
130
266
  * Descargar PDF de Factura (Retorna el Stream / ArrayBuffer)
131
267
  */
132
- getInvoicePdfBuffer(id: string): Promise<Buffer>;
268
+ getInvoicePdfBuffer(id: string, options?: {
269
+ format?: 'a4' | 'ticket';
270
+ }): Promise<Buffer>;
271
+ /**
272
+ * Listar Puntos de Venta Habilitados para FacturaciΓ³n ElectrΓ³nica
273
+ */
274
+ listPuntosDeVenta(): Promise<PuntoDeVenta[]>;
133
275
  /**
134
276
  * Obtener Consumos y Estado del Plan (Billing)
135
277
  */
@@ -142,4 +284,38 @@ export declare class KeyCaeClient {
142
284
  * Guardar / Actualizar Ajustes de Telegram
143
285
  */
144
286
  saveTelegramSettings(data: TelegramSettingsInput): Promise<any>;
287
+ /**
288
+ * Health Check de la API
289
+ */
290
+ health(): Promise<HealthResponse>;
291
+ /**
292
+ * Obtener tabla de condiciones IVA del receptor (15 cΓ³digos oficiales ARCA)
293
+ */
294
+ getCondicionesIva(): Promise<CondicionesIvaResponse>;
295
+ /**
296
+ * Consultar cotizaciΓ³n de una moneda extranjera vs peso (vΓ­a ARCA)
297
+ */
298
+ getCotizacionMoneda(moneda: string): Promise<{
299
+ moneda: string;
300
+ cotizacion: number;
301
+ }>;
302
+ /**
303
+ * Crear una subcuenta completa (usuario + perfil + API Key) para un
304
+ * cliente final de tu ERP. La password y api_key se devuelven una sola vez.
305
+ */
306
+ createPartnerSubaccount(data: PartnerSubaccountInput): Promise<PartnerSubaccountResponse>;
307
+ /**
308
+ * Listar los clientes vinculados a tu partner, con plan y consumo mensual.
309
+ */
310
+ listPartnerSubaccounts(): Promise<PartnerClientsResponse>;
311
+ /**
312
+ * Pre-autorizar el CUIT de un cliente para facturaciΓ³n consolidada
313
+ * (el cliente no pasarΓ‘ por la pasarela de pago al registrarse).
314
+ */
315
+ preauthorizeCuit(cuit: string): Promise<PartnerPreauthResponse>;
316
+ /**
317
+ * Consultar la configuraciΓ³n pΓΊblica de co-branding de un partner
318
+ * (endpoint pΓΊblico β€” no requiere autenticaciΓ³n).
319
+ */
320
+ getPartnerConfig(partnerId: string): Promise<PartnerPublicConfig>;
145
321
  }
package/dist/index.js CHANGED
@@ -5,10 +5,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.KeyCaeClient = void 0;
7
7
  const node_fetch_1 = __importDefault(require("node-fetch"));
8
+ // ════════════════════════════════════════════════════════════════════
9
+ // CLIENT
10
+ // ════════════════════════════════════════════════════════════════════
8
11
  class KeyCaeClient {
9
- constructor(apiKey, baseUrl = 'https://api.keycae.ar') {
12
+ constructor(apiKey, baseUrl = 'https://keycae.ar') {
10
13
  this.apiKey = apiKey;
11
- this.baseUrl = baseUrl;
14
+ this.baseUrl = baseUrl.replace(/\/$/, '');
12
15
  }
13
16
  async request(method, path, body, idempotencyKey) {
14
17
  const headers = {
@@ -24,21 +27,60 @@ class KeyCaeClient {
24
27
  body: body ? JSON.stringify(body) : undefined
25
28
  });
26
29
  if (!response.ok) {
27
- let errorDetails = '';
30
+ let errorData;
28
31
  try {
29
- errorDetails = await response.text();
32
+ errorData = await response.json();
30
33
  }
31
- catch (e) { }
32
- throw new Error(`KeyCAE API Error (${response.status}): ${errorDetails || response.statusText}`);
34
+ catch {
35
+ const text = await response.text().catch(() => '');
36
+ throw new Error(`KeyCAE API Error (${response.status}): ${text || response.statusText}`);
37
+ }
38
+ const message = errorData?.error?.message || JSON.stringify(errorData);
39
+ const hint = errorData?.error?.ai_action_hint || '';
40
+ throw new Error(`KeyCAE API Error (${response.status}): ${message}${hint ? ` [hint: ${hint}]` : ''}`);
33
41
  }
34
42
  return response.json();
35
43
  }
44
+ // ── Taxpayers ─────────────────────────────────────────────────────
36
45
  /**
37
46
  * Consultar Contribuyente en PadrΓ³n ARCA
38
47
  */
39
48
  async getTaxpayer(cuit) {
40
49
  return this.request('GET', `/v1/taxpayers/${cuit}`);
41
50
  }
51
+ /**
52
+ * Verificar quΓ© tipos de factura puede emitir un CUIT segΓΊn su condiciΓ³n fiscal
53
+ */
54
+ async checkEmissionCapability(cuit) {
55
+ const taxpayer = await this.getTaxpayer(cuit);
56
+ const condition = taxpayer.condicion_iva || taxpayer.estado || '';
57
+ let compatibleTypes = [];
58
+ let recommendation = '';
59
+ if (condition.toLowerCase().includes('monotributo')) {
60
+ compatibleTypes = ['C', 'M'];
61
+ recommendation = 'Como Monotributista, podΓ©s emitir Factura C (exenta) o Factura M (monotributo). NO podΓ©s emitir Factura A o B.';
62
+ }
63
+ else if (condition.toLowerCase().includes('responsable inscripto') || condition.toLowerCase().includes('ri')) {
64
+ compatibleTypes = ['A', 'B'];
65
+ recommendation = 'Como Responsable Inscripto, podΓ©s emitir Factura A (IVA discriminado) o Factura B (consumidor final).';
66
+ }
67
+ else if (condition.toLowerCase().includes('exento')) {
68
+ compatibleTypes = ['C'];
69
+ recommendation = 'Como Exento, solo podΓ©s emitir Factura C (exenta).';
70
+ }
71
+ else {
72
+ compatibleTypes = ['C'];
73
+ recommendation = 'No se pudo determinar la condiciΓ³n impositiva. Se recomienda Factura C por defecto.';
74
+ }
75
+ return {
76
+ cuit,
77
+ condicion_iva: condition,
78
+ compatible_types: compatibleTypes,
79
+ recommendation,
80
+ tip: 'UsΓ‘ estos tipos al emitir facturas con emitInvoice para evitar errores de ARCA.'
81
+ };
82
+ }
83
+ // ── Delegations ───────────────────────────────────────────────────
42
84
  /**
43
85
  * Registrar / Iniciar Direct Delegation
44
86
  */
@@ -51,12 +93,19 @@ class KeyCaeClient {
51
93
  async checkDelegationStatus() {
52
94
  return this.request('GET', '/v1/delegations/status');
53
95
  }
96
+ // ── Credentials (KMS) ────────────────────────────────────────────
54
97
  /**
55
98
  * Crear BΓ³veda de Claves KMS & Generar CSR
56
99
  */
57
100
  async createCredential(data) {
58
101
  return this.request('POST', '/v1/credentials', data);
59
102
  }
103
+ /**
104
+ * Listar Credenciales Digitales Registradas
105
+ */
106
+ async listCredentials() {
107
+ return this.request('GET', '/v1/credentials');
108
+ }
60
109
  /**
61
110
  * Importar Credenciales de Firma Existentes (.key y .crt)
62
111
  */
@@ -75,17 +124,35 @@ class KeyCaeClient {
75
124
  async deleteCredential(id) {
76
125
  return this.request('DELETE', `/v1/credentials/${id}`);
77
126
  }
127
+ // ── Invoices ──────────────────────────────────────────────────────
78
128
  /**
79
129
  * Emitir Factura ElectrΓ³nica Homologada (CAE)
80
130
  */
81
131
  async emitInvoice(data, idempotencyKey) {
82
132
  return this.request('POST', '/v1/invoices', data, idempotencyKey);
83
133
  }
134
+ /**
135
+ * Obtener Detalles de una Factura por ID
136
+ */
137
+ async getInvoice(id) {
138
+ return this.request('GET', `/v1/invoices/${id}`);
139
+ }
140
+ /**
141
+ * Listar Facturas Recientes
142
+ */
143
+ async listInvoices(limit = 10, offset = 0) {
144
+ const params = new URLSearchParams({ limit: String(limit), offset: String(offset) });
145
+ return this.request('GET', `/v1/invoices?${params}`);
146
+ }
84
147
  /**
85
148
  * Descargar PDF de Factura (Retorna el Stream / ArrayBuffer)
86
149
  */
87
- async getInvoicePdfBuffer(id) {
88
- const response = await (0, node_fetch_1.default)(`${this.baseUrl}/v1/invoices/${id}/pdf`, {
150
+ async getInvoicePdfBuffer(id, options) {
151
+ const url = new URL(`${this.baseUrl}/v1/invoices/${id}/pdf`);
152
+ if (options?.format) {
153
+ url.searchParams.append('format', options.format);
154
+ }
155
+ const response = await (0, node_fetch_1.default)(url.toString(), {
89
156
  method: 'GET',
90
157
  headers: {
91
158
  'Authorization': `Bearer ${this.apiKey}`
@@ -94,15 +161,23 @@ class KeyCaeClient {
94
161
  if (!response.ok) {
95
162
  throw new Error(`Failed to fetch PDF (${response.status})`);
96
163
  }
97
- const arrayBuffer = await response.arrayBuffer();
98
- return Buffer.from(arrayBuffer);
164
+ return Buffer.from(await response.arrayBuffer());
165
+ }
166
+ // ── Puntos de Venta ───────────────────────────────────────────────
167
+ /**
168
+ * Listar Puntos de Venta Habilitados para FacturaciΓ³n ElectrΓ³nica
169
+ */
170
+ async listPuntosDeVenta() {
171
+ return this.request('GET', '/v1/pos');
99
172
  }
173
+ // ── Billing ───────────────────────────────────────────────────────
100
174
  /**
101
175
  * Obtener Consumos y Estado del Plan (Billing)
102
176
  */
103
177
  async getBillingStatus() {
104
178
  return this.request('GET', '/v1/billing/status');
105
179
  }
180
+ // ── Telegram Settings ─────────────────────────────────────────────
106
181
  /**
107
182
  * Obtener Ajustes de Telegram por Tenant
108
183
  */
@@ -115,5 +190,56 @@ class KeyCaeClient {
115
190
  async saveTelegramSettings(data) {
116
191
  return this.request('POST', '/v1/settings/telegram', data);
117
192
  }
193
+ // ── Health ────────────────────────────────────────────────────────
194
+ /**
195
+ * Health Check de la API
196
+ */
197
+ async health() {
198
+ return this.request('GET', '/health');
199
+ }
200
+ // ── CondiciΓ³n IVA Receptor ──────────────────────────────────────
201
+ /**
202
+ * Obtener tabla de condiciones IVA del receptor (15 cΓ³digos oficiales ARCA)
203
+ */
204
+ async getCondicionesIva() {
205
+ return this.request('GET', '/v1/taxpayers/condiciones-iva');
206
+ }
207
+ // ── CotizaciΓ³n de Moneda ────────────────────────────────────────
208
+ /**
209
+ * Consultar cotizaciΓ³n de una moneda extranjera vs peso (vΓ­a ARCA)
210
+ */
211
+ async getCotizacionMoneda(moneda) {
212
+ return this.request('GET', `/v1/cotizacion/${moneda}`);
213
+ }
214
+ // ── Partners (ERP / SaaS) ────────────────────────────────────────
215
+ // Estos mΓ©todos requieren instanciar el cliente con tu API Key de
216
+ // Partner (sk_partner_live_...) β€” solo desde tu backend.
217
+ /**
218
+ * Crear una subcuenta completa (usuario + perfil + API Key) para un
219
+ * cliente final de tu ERP. La password y api_key se devuelven una sola vez.
220
+ */
221
+ async createPartnerSubaccount(data) {
222
+ return this.request('POST', '/v1/partners/subaccounts', data);
223
+ }
224
+ /**
225
+ * Listar los clientes vinculados a tu partner, con plan y consumo mensual.
226
+ */
227
+ async listPartnerSubaccounts() {
228
+ return this.request('GET', '/v1/partners/subaccounts');
229
+ }
230
+ /**
231
+ * Pre-autorizar el CUIT de un cliente para facturaciΓ³n consolidada
232
+ * (el cliente no pasarΓ‘ por la pasarela de pago al registrarse).
233
+ */
234
+ async preauthorizeCuit(cuit) {
235
+ return this.request('POST', '/v1/partners/preauthorize', { cuit });
236
+ }
237
+ /**
238
+ * Consultar la configuraciΓ³n pΓΊblica de co-branding de un partner
239
+ * (endpoint pΓΊblico β€” no requiere autenticaciΓ³n).
240
+ */
241
+ async getPartnerConfig(partnerId) {
242
+ return this.request('GET', `/v1/partners/${encodeURIComponent(partnerId)}/config`);
243
+ }
118
244
  }
119
245
  exports.KeyCaeClient = KeyCaeClient;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "keycae-ts",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "description": "Official TypeScript & JavaScript SDK client for KeyCAE.ar impositive compliance API (ARCA)",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -20,6 +20,11 @@
20
20
  ],
21
21
  "author": "KeyCAE Community",
22
22
  "license": "MIT",
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "https://github.com/AMKRS3/keycae-packages",
26
+ "directory": "keycae-ts"
27
+ },
23
28
  "dependencies": {
24
29
  "node-fetch": "^2.6.9"
25
30
  },
package/src/index.ts CHANGED
@@ -1,5 +1,16 @@
1
1
  import fetch from 'node-fetch';
2
2
 
3
+ // ════════════════════════════════════════════════════════════════════
4
+ // INTERFACES
5
+ // ════════════════════════════════════════════════════════════════════
6
+
7
+ export interface DomicilioFiscal {
8
+ direccion: string | null;
9
+ localidad: string | null;
10
+ cod_postal: string | null;
11
+ provincia: string | null;
12
+ }
13
+
3
14
  export interface TaxpayerResponse {
4
15
  cuit: string;
5
16
  nombre: string;
@@ -7,26 +18,78 @@ export interface TaxpayerResponse {
7
18
  categoria_monotributo?: string;
8
19
  es_iva_inscripto: boolean;
9
20
  estado: string;
21
+ condicion_iva?: string;
22
+ actividades?: string[];
23
+ domicilio_fiscal?: DomicilioFiscal;
10
24
  }
11
25
 
12
26
  export interface InvoiceReceptor {
13
- tipo_doc: 'DNI' | 'CUIT' | 'CUIL' | 'PASAPORTE';
27
+ tipo_doc: 'DNI' | 'CUIT' | 'CUIL' | 'PASAPORTE' | 'SIN_IDENTIFICAR';
14
28
  nro_doc: string;
29
+ razon_social?: string;
30
+ condicion_iva?: string;
15
31
  }
16
32
 
17
33
  export interface InvoiceItem {
18
34
  descripcion: string;
19
35
  precio: number;
36
+ cantidad?: number;
37
+ alicuota_iva?: number;
38
+ }
39
+
40
+ export interface Tributo {
41
+ id: number;
42
+ descripcion: string;
43
+ base_imponible: number;
44
+ alicuota: number;
45
+ importe: number;
46
+ }
47
+
48
+ export interface Opcional {
49
+ id: string;
50
+ valor: string;
51
+ }
52
+
53
+ export interface CondicionesIvaResponse {
54
+ condiciones: { codigo: number; nombre: string }[];
20
55
  }
21
56
 
22
57
  export interface InvoiceInput {
23
58
  cuit_emisor: string;
24
59
  punto_de_venta: number;
25
- tipo_comprobante: 'A' | 'B' | 'C' | 'M';
60
+ tipo_comprobante: 'A' | 'B' | 'C' | 'M' | 'E'
61
+ | 'NCA' | 'NCB' | 'NCC' | 'NCE' | 'NCM'
62
+ | 'NDA' | 'NDB' | 'NDC' | 'NDE' | 'NDM'
63
+ | 'FCE_A' | 'FCE_B' | 'FCE_C'
64
+ | 'FCE_NDA' | 'FCE_NDB' | 'FCE_NDC'
65
+ | 'FCE_NCA' | 'FCE_NCB' | 'FCE_NCC';
26
66
  receptor: InvoiceReceptor;
27
67
  conceptos: InvoiceItem[];
68
+ /**
69
+ * Default `true`: los `conceptos[].precio` se envΓ­an con IVA incluido (precio final).
70
+ * Con `false`, los precios se interpretan como netos (sin IVA) y KeyCAE calcula
71
+ * y adiciona el IVA segΓΊn la `alicuota_iva` de cada Γ­tem.
72
+ * Sin efecto en comprobantes sin discriminaciΓ³n de IVA (tipo C / E).
73
+ */
74
+ iva_incluido?: boolean;
75
+ tributos?: Tributo[];
76
+ moneda?: string;
77
+ moneda_cotizacion?: number;
78
+ fecha_comprobante?: string;
79
+ fecha_servicio_desde?: string;
80
+ fecha_servicio_hasta?: string;
81
+ fecha_vto_pago?: string;
82
+ condicion_iva_receptor?: number;
83
+ opcionales?: Opcional[];
28
84
  brand_logo_url?: string;
29
85
  brand_color?: string;
86
+ cbtes_asociados?: {
87
+ tipo: string | number;
88
+ punto_de_venta: number;
89
+ numero: number;
90
+ cuit?: string;
91
+ fecha?: string;
92
+ }[];
30
93
  }
31
94
 
32
95
  export interface InvoiceResponse {
@@ -72,7 +135,7 @@ export interface DelegationInput {
72
135
 
73
136
  export interface DelegationResponse {
74
137
  id: string;
75
- status: 'pending' | 'accepted' | 'rejected';
138
+ status: 'pending' | 'accepted' | 'rejected' | 'pending_auto';
76
139
  cuit: string;
77
140
  organization: string;
78
141
  representativeCuit: string;
@@ -104,13 +167,92 @@ export interface KmsImportInput {
104
167
  private_key: string;
105
168
  }
106
169
 
170
+ export interface PuntoDeVenta {
171
+ numero: number;
172
+ tipoEmision: string;
173
+ tipoAutomatizacion?: string;
174
+ fechaServicioDesde?: string;
175
+ fechaServicioHasta?: string;
176
+ }
177
+
178
+ export interface EmissionCapability {
179
+ cuit: string;
180
+ condicion_iva: string;
181
+ compatible_types: string[];
182
+ recommendation: string;
183
+ tip: string;
184
+ }
185
+
186
+ export interface HealthResponse {
187
+ status: string;
188
+ version?: string;
189
+ uptime?: number;
190
+ }
191
+
192
+ // ── Partners (ERP / SaaS Integrations) ──────────────────────────────
193
+
194
+ export interface PartnerSubaccountInput {
195
+ /** CUIT fiscal del cliente final (11 dΓ­gitos, sin guiones) */
196
+ cuit: string;
197
+ /** RazΓ³n social del cliente final */
198
+ organization: string;
199
+ /** Email de acceso del cliente final */
200
+ email: string;
201
+ }
202
+
203
+ export interface PartnerSubaccountResponse {
204
+ id: string;
205
+ cuit: string;
206
+ organization: string;
207
+ email: string;
208
+ /** ContraseΓ±a generada β€” se devuelve UNA sola vez. Entregar por canal seguro. */
209
+ password: string;
210
+ /** API Key live de la subcuenta β€” se devuelve UNA sola vez. */
211
+ api_key: string;
212
+ partner_id: string;
213
+ }
214
+
215
+ export interface PartnerClient {
216
+ cuit: string;
217
+ organization: string;
218
+ email: string;
219
+ plan: 'free' | 'developer' | 'platform';
220
+ invoices_this_month: number;
221
+ created_at: string | null;
222
+ }
223
+
224
+ export interface PartnerClientsResponse {
225
+ partner_id: string;
226
+ total: number;
227
+ clients: PartnerClient[];
228
+ }
229
+
230
+ export interface PartnerPreauthResponse {
231
+ success: boolean;
232
+ message: string;
233
+ partner_id: string;
234
+ cuit: string;
235
+ }
236
+
237
+ export interface PartnerPublicConfig {
238
+ id: string;
239
+ name: string;
240
+ logo_url: string;
241
+ brand_color: string;
242
+ billing_mode: 'decentralized' | 'consolidated';
243
+ }
244
+
245
+ // ════════════════════════════════════════════════════════════════════
246
+ // CLIENT
247
+ // ════════════════════════════════════════════════════════════════════
248
+
107
249
  export class KeyCaeClient {
108
250
  private apiKey: string;
109
251
  private baseUrl: string;
110
252
 
111
- constructor(apiKey: string, baseUrl: string = 'https://api.keycae.ar') {
253
+ constructor(apiKey: string, baseUrl: string = 'https://keycae.ar') {
112
254
  this.apiKey = apiKey;
113
- this.baseUrl = baseUrl;
255
+ this.baseUrl = baseUrl.replace(/\/$/, '');
114
256
  }
115
257
 
116
258
  private async request<T>(
@@ -135,16 +277,23 @@ export class KeyCaeClient {
135
277
  });
136
278
 
137
279
  if (!response.ok) {
138
- let errorDetails = '';
280
+ let errorData: any;
139
281
  try {
140
- errorDetails = await response.text();
141
- } catch (e) {}
142
- throw new Error(`KeyCAE API Error (${response.status}): ${errorDetails || response.statusText}`);
282
+ errorData = await response.json();
283
+ } catch {
284
+ const text = await response.text().catch(() => '');
285
+ throw new Error(`KeyCAE API Error (${response.status}): ${text || response.statusText}`);
286
+ }
287
+ const message = errorData?.error?.message || JSON.stringify(errorData);
288
+ const hint = errorData?.error?.ai_action_hint || '';
289
+ throw new Error(`KeyCAE API Error (${response.status}): ${message}${hint ? ` [hint: ${hint}]` : ''}`);
143
290
  }
144
291
 
145
292
  return response.json() as Promise<T>;
146
293
  }
147
294
 
295
+ // ── Taxpayers ─────────────────────────────────────────────────────
296
+
148
297
  /**
149
298
  * Consultar Contribuyente en PadrΓ³n ARCA
150
299
  */
@@ -152,6 +301,40 @@ export class KeyCaeClient {
152
301
  return this.request<TaxpayerResponse>('GET', `/v1/taxpayers/${cuit}`);
153
302
  }
154
303
 
304
+ /**
305
+ * Verificar quΓ© tipos de factura puede emitir un CUIT segΓΊn su condiciΓ³n fiscal
306
+ */
307
+ async checkEmissionCapability(cuit: string): Promise<EmissionCapability> {
308
+ const taxpayer = await this.getTaxpayer(cuit);
309
+ const condition = taxpayer.condicion_iva || taxpayer.estado || '';
310
+ let compatibleTypes: string[] = [];
311
+ let recommendation = '';
312
+
313
+ if (condition.toLowerCase().includes('monotributo')) {
314
+ compatibleTypes = ['C', 'M'];
315
+ recommendation = 'Como Monotributista, podΓ©s emitir Factura C (exenta) o Factura M (monotributo). NO podΓ©s emitir Factura A o B.';
316
+ } else if (condition.toLowerCase().includes('responsable inscripto') || condition.toLowerCase().includes('ri')) {
317
+ compatibleTypes = ['A', 'B'];
318
+ recommendation = 'Como Responsable Inscripto, podΓ©s emitir Factura A (IVA discriminado) o Factura B (consumidor final).';
319
+ } else if (condition.toLowerCase().includes('exento')) {
320
+ compatibleTypes = ['C'];
321
+ recommendation = 'Como Exento, solo podΓ©s emitir Factura C (exenta).';
322
+ } else {
323
+ compatibleTypes = ['C'];
324
+ recommendation = 'No se pudo determinar la condiciΓ³n impositiva. Se recomienda Factura C por defecto.';
325
+ }
326
+
327
+ return {
328
+ cuit,
329
+ condicion_iva: condition,
330
+ compatible_types: compatibleTypes,
331
+ recommendation,
332
+ tip: 'UsΓ‘ estos tipos al emitir facturas con emitInvoice para evitar errores de ARCA.'
333
+ };
334
+ }
335
+
336
+ // ── Delegations ───────────────────────────────────────────────────
337
+
155
338
  /**
156
339
  * Registrar / Iniciar Direct Delegation
157
340
  */
@@ -166,6 +349,8 @@ export class KeyCaeClient {
166
349
  return this.request<DelegationResponse>('GET', '/v1/delegations/status');
167
350
  }
168
351
 
352
+ // ── Credentials (KMS) ────────────────────────────────────────────
353
+
169
354
  /**
170
355
  * Crear BΓ³veda de Claves KMS & Generar CSR
171
356
  */
@@ -173,6 +358,13 @@ export class KeyCaeClient {
173
358
  return this.request<KmsCredentialResponse>('POST', '/v1/credentials', data);
174
359
  }
175
360
 
361
+ /**
362
+ * Listar Credenciales Digitales Registradas
363
+ */
364
+ async listCredentials(): Promise<KmsCredentialResponse[]> {
365
+ return this.request<KmsCredentialResponse[]>('GET', '/v1/credentials');
366
+ }
367
+
176
368
  /**
177
369
  * Importar Credenciales de Firma Existentes (.key y .crt)
178
370
  */
@@ -194,6 +386,8 @@ export class KeyCaeClient {
194
386
  return this.request<any>('DELETE', `/v1/credentials/${id}`);
195
387
  }
196
388
 
389
+ // ── Invoices ──────────────────────────────────────────────────────
390
+
197
391
  /**
198
392
  * Emitir Factura ElectrΓ³nica Homologada (CAE)
199
393
  */
@@ -201,11 +395,30 @@ export class KeyCaeClient {
201
395
  return this.request<InvoiceResponse>('POST', '/v1/invoices', data, idempotencyKey);
202
396
  }
203
397
 
398
+ /**
399
+ * Obtener Detalles de una Factura por ID
400
+ */
401
+ async getInvoice(id: string): Promise<InvoiceResponse> {
402
+ return this.request<InvoiceResponse>('GET', `/v1/invoices/${id}`);
403
+ }
404
+
405
+ /**
406
+ * Listar Facturas Recientes
407
+ */
408
+ async listInvoices(limit: number = 10, offset: number = 0): Promise<{ invoices: InvoiceResponse[]; total: number }> {
409
+ const params = new URLSearchParams({ limit: String(limit), offset: String(offset) });
410
+ return this.request<any>('GET', `/v1/invoices?${params}`);
411
+ }
412
+
204
413
  /**
205
414
  * Descargar PDF de Factura (Retorna el Stream / ArrayBuffer)
206
415
  */
207
- async getInvoicePdfBuffer(id: string): Promise<Buffer> {
208
- const response = await fetch(`${this.baseUrl}/v1/invoices/${id}/pdf`, {
416
+ async getInvoicePdfBuffer(id: string, options?: { format?: 'a4' | 'ticket' }): Promise<Buffer> {
417
+ const url = new URL(`${this.baseUrl}/v1/invoices/${id}/pdf`);
418
+ if (options?.format) {
419
+ url.searchParams.append('format', options.format);
420
+ }
421
+ const response = await fetch(url.toString(), {
209
422
  method: 'GET',
210
423
  headers: {
211
424
  'Authorization': `Bearer ${this.apiKey}`
@@ -216,10 +429,20 @@ export class KeyCaeClient {
216
429
  throw new Error(`Failed to fetch PDF (${response.status})`);
217
430
  }
218
431
 
219
- const arrayBuffer = await response.arrayBuffer();
220
- return Buffer.from(arrayBuffer);
432
+ return Buffer.from(await response.arrayBuffer());
221
433
  }
222
434
 
435
+ // ── Puntos de Venta ───────────────────────────────────────────────
436
+
437
+ /**
438
+ * Listar Puntos de Venta Habilitados para FacturaciΓ³n ElectrΓ³nica
439
+ */
440
+ async listPuntosDeVenta(): Promise<PuntoDeVenta[]> {
441
+ return this.request<PuntoDeVenta[]>('GET', '/v1/pos');
442
+ }
443
+
444
+ // ── Billing ───────────────────────────────────────────────────────
445
+
223
446
  /**
224
447
  * Obtener Consumos y Estado del Plan (Billing)
225
448
  */
@@ -227,6 +450,8 @@ export class KeyCaeClient {
227
450
  return this.request<BillingStatusResponse>('GET', '/v1/billing/status');
228
451
  }
229
452
 
453
+ // ── Telegram Settings ─────────────────────────────────────────────
454
+
230
455
  /**
231
456
  * Obtener Ajustes de Telegram por Tenant
232
457
  */
@@ -240,4 +465,66 @@ export class KeyCaeClient {
240
465
  async saveTelegramSettings(data: TelegramSettingsInput): Promise<any> {
241
466
  return this.request<any>('POST', '/v1/settings/telegram', data);
242
467
  }
468
+
469
+ // ── Health ────────────────────────────────────────────────────────
470
+
471
+ /**
472
+ * Health Check de la API
473
+ */
474
+ async health(): Promise<HealthResponse> {
475
+ return this.request<HealthResponse>('GET', '/health');
476
+ }
477
+
478
+ // ── CondiciΓ³n IVA Receptor ──────────────────────────────────────
479
+
480
+ /**
481
+ * Obtener tabla de condiciones IVA del receptor (15 cΓ³digos oficiales ARCA)
482
+ */
483
+ async getCondicionesIva(): Promise<CondicionesIvaResponse> {
484
+ return this.request<CondicionesIvaResponse>('GET', '/v1/taxpayers/condiciones-iva');
485
+ }
486
+
487
+ // ── CotizaciΓ³n de Moneda ────────────────────────────────────────
488
+
489
+ /**
490
+ * Consultar cotizaciΓ³n de una moneda extranjera vs peso (vΓ­a ARCA)
491
+ */
492
+ async getCotizacionMoneda(moneda: string): Promise<{ moneda: string; cotizacion: number }> {
493
+ return this.request<any>('GET', `/v1/cotizacion/${moneda}`);
494
+ }
495
+
496
+ // ── Partners (ERP / SaaS) ────────────────────────────────────────
497
+ // Estos mΓ©todos requieren instanciar el cliente con tu API Key de
498
+ // Partner (sk_partner_live_...) β€” solo desde tu backend.
499
+
500
+ /**
501
+ * Crear una subcuenta completa (usuario + perfil + API Key) para un
502
+ * cliente final de tu ERP. La password y api_key se devuelven una sola vez.
503
+ */
504
+ async createPartnerSubaccount(data: PartnerSubaccountInput): Promise<PartnerSubaccountResponse> {
505
+ return this.request<PartnerSubaccountResponse>('POST', '/v1/partners/subaccounts', data);
506
+ }
507
+
508
+ /**
509
+ * Listar los clientes vinculados a tu partner, con plan y consumo mensual.
510
+ */
511
+ async listPartnerSubaccounts(): Promise<PartnerClientsResponse> {
512
+ return this.request<PartnerClientsResponse>('GET', '/v1/partners/subaccounts');
513
+ }
514
+
515
+ /**
516
+ * Pre-autorizar el CUIT de un cliente para facturaciΓ³n consolidada
517
+ * (el cliente no pasarΓ‘ por la pasarela de pago al registrarse).
518
+ */
519
+ async preauthorizeCuit(cuit: string): Promise<PartnerPreauthResponse> {
520
+ return this.request<PartnerPreauthResponse>('POST', '/v1/partners/preauthorize', { cuit });
521
+ }
522
+
523
+ /**
524
+ * Consultar la configuraciΓ³n pΓΊblica de co-branding de un partner
525
+ * (endpoint pΓΊblico β€” no requiere autenticaciΓ³n).
526
+ */
527
+ async getPartnerConfig(partnerId: string): Promise<PartnerPublicConfig> {
528
+ return this.request<PartnerPublicConfig>('GET', `/v1/partners/${encodeURIComponent(partnerId)}/config`);
529
+ }
243
530
  }