@ramiidv/arca-fecred 0.2.0 → 0.4.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 +124 -0
- package/README.md +125 -286
- package/dist/arca-fecred.d.ts +63 -109
- package/dist/arca-fecred.d.ts.map +1 -1
- package/dist/arca-fecred.js +107 -315
- package/dist/arca-fecred.js.map +1 -1
- package/dist/constants.d.ts +73 -75
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +65 -95
- package/dist/constants.js.map +1 -1
- package/dist/fecred-client.d.ts +86 -89
- package/dist/fecred-client.d.ts.map +1 -1
- package/dist/fecred-client.js +166 -162
- package/dist/fecred-client.js.map +1 -1
- package/dist/index.d.ts +6 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -13
- package/dist/index.js.map +1 -1
- package/dist/schemas.d.ts +165 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +376 -0
- package/dist/schemas.js.map +1 -0
- package/dist/types.d.ts +401 -198
- package/dist/types.d.ts.map +1 -1
- package/llms.txt +65 -142
- package/package.json +20 -21
- package/dist/validation.d.ts +0 -26
- package/dist/validation.d.ts.map +0 -1
- package/dist/validation.js +0 -161
- package/dist/validation.js.map +0 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 8c02c30: API uniforme entre los SDKs (los nombres anteriores siguen funcionando,
|
|
8
|
+
marcados `@deprecated`, hasta la próxima major):
|
|
9
|
+
|
|
10
|
+
- arca-facturacion: la clase principal es `ArcaFacturacion` (`Arca` queda como
|
|
11
|
+
alias). Nuevo `status()` → `{ wsfe, wsfex }` con `ServiceStatus` y el
|
|
12
|
+
`ServerStatus` de arca-common (`appserver`/`dbserver`/`authserver`);
|
|
13
|
+
`serverStatus()`/`serverStatusExpo()` y su `ServerStatus` en mayúsculas
|
|
14
|
+
quedan deprecados.
|
|
15
|
+
- arca-agro: `status()` (antes `serverStatus()`).
|
|
16
|
+
- arca-fecred: el cliente de bajo nivel es `client` (antes `fecred`).
|
|
17
|
+
- arca-common: `ServiceStatus` y `statusOf()` para el estado de varios servicios.
|
|
18
|
+
- bed68e8: Paquetes solo ESM y Node >= 20.19. `arca-common`, `arca-facturacion` y
|
|
19
|
+
`arca-padron` dejan de publicar un build CommonJS: desde CommonJS se cargan con
|
|
20
|
+
`require()` (require(esm), Node >= 20.19 / 22.12). Todos los paquetes pasan a
|
|
21
|
+
requerir Node >= 20.19.0 (Node 18 y 20 sin soporte). El código vive ahora en el
|
|
22
|
+
monorepo `arca-sdks`.
|
|
23
|
+
- f8bd053: Las clases principales extienden `ArcaSdkBase` de arca-common, así que todos
|
|
24
|
+
los SDKs tienen la misma base: `wsaa`, `cuit`, `production`, `on()`/`off()`,
|
|
25
|
+
`clearAuthCache()`, `config.wsaa` (WsaaClient compartido) y `config.signal`
|
|
26
|
+
(signal global). arca-mtxca acepta `endpoints: { mtxca, wsaa }` (`endpoint` y
|
|
27
|
+
`wsaaEndpoint` quedan deprecados). Los `dummy`/`status` validan la respuesta con
|
|
28
|
+
`parseServerStatus`: si falta un campo lanzan `ArcaSoapError`.
|
|
29
|
+
- c9f1444: Requests y respuestas se validan, serializan y decodifican con el DSL de
|
|
30
|
+
`@ramiidv/arca-common/schema`, transcripto del XSD oficial de cada servicio.
|
|
31
|
+
|
|
32
|
+
- Corrección: las respuestas se parsean sin conversión numérica, así que los
|
|
33
|
+
`xs:string` con contenido numérico ya no pierden ceros a la izquierda ni
|
|
34
|
+
decimales (ej: `"0012"`, `"1.50"`, `DocNro`, `codigoSeguridad`).
|
|
35
|
+
- Los campos desconocidos en el input se rechazan con `ArcaValidationError`
|
|
36
|
+
(antes se ignoraban).
|
|
37
|
+
- Todos los errores de validación se informan juntos (`details`), con mensajes
|
|
38
|
+
del tipo `campo: motivo`. Cambió el texto de los mensajes.
|
|
39
|
+
- arca-fecred deja de recortar espacios de los textos y envía `codCtaCte` tal
|
|
40
|
+
cual; porcentaje y cotización se envían con decimales fijos.
|
|
41
|
+
|
|
42
|
+
### Patch Changes
|
|
43
|
+
|
|
44
|
+
- 20ecf7d: DSL de schemas, segunda versión:
|
|
45
|
+
|
|
46
|
+
- Corrección: `dec()` redondea sobre el valor decimal escrito (`8.575` →
|
|
47
|
+
`8.58`; antes daba `8.57` por la representación binaria). Afecta los importes
|
|
48
|
+
que los SDKs envían redondeados.
|
|
49
|
+
- `must()` rechaza también el valor vacío; los elementos `xsi:nil` cuentan
|
|
50
|
+
como ausentes (en una lista, como lista vacía); `must()` en listas exige el
|
|
51
|
+
elemento; un objeto opcional vacío se omite y uno obligatorio valida sus hijos.
|
|
52
|
+
- Al decodificar se validan enteros (`int()`) y valores permitidos
|
|
53
|
+
(`str({ values })`).
|
|
54
|
+
- Nuevos: `siNo()` (S/N ↔ boolean), `double()`, `xml(nombre, campo)` (nombre
|
|
55
|
+
distinto en el XML), `custom(encode, decode)`, `roundHalfUp()` y
|
|
56
|
+
`decodeResponse(..., { emptyLists: 'omit' })`.
|
|
57
|
+
- Updated dependencies [8c02c30]
|
|
58
|
+
- Updated dependencies [f8bd053]
|
|
59
|
+
- Updated dependencies [242fb5f]
|
|
60
|
+
- Updated dependencies [fd438bc]
|
|
61
|
+
- Updated dependencies [bed68e8]
|
|
62
|
+
- Updated dependencies [20ecf7d]
|
|
63
|
+
- Updated dependencies [b86db00]
|
|
64
|
+
- @ramiidv/arca-common@0.5.0
|
|
65
|
+
|
|
66
|
+
## 0.3.0 (2026-11-01)
|
|
67
|
+
|
|
68
|
+
Revisión completa contra el WSDL de FECredService. La 0.2.0 no podía operar contra ARCA.
|
|
69
|
+
|
|
70
|
+
### Breaking
|
|
71
|
+
- Requiere `@ramiidv/arca-common` `^0.4.0`. `ArcaFecredConfig` extiende `ArcaBaseConfig` (`cuit: number | string`).
|
|
72
|
+
- `consultarMontoObligadoRecepcion({ cuitConsultada, fechaEmision })`: ahora recibe un objeto (el XSD exige `fechaEmision`).
|
|
73
|
+
- `consultarCtasCtes` y `consultarComprobantes` reciben `{ rol, cuitContraparte?, fecha?: { tipo, desde, hasta }, ... }` (antes `fechaDesde`/`fechaHasta`/`cuitEmisor`/`cuitReceptor`, que no existen en el XSD) y devuelven `{ ctasCtes | comprobantes, nroPagina?, hayMas?, evento?, observaciones }` en lugar de un array.
|
|
74
|
+
- `aceptarFECred(params)`, `rechazarFECred(params)`: reciben `idCtaCte` (`{ codCtaCte }` o `{ idFactura }`) y los campos obligatorios del XSD (`saldoAceptado`, `codMoneda`, `cotizacionMonedaUlt`; `motivos[]` con `codMotivo`, `descMotivo`, `justificacion`). Devuelven `{ resultado, idCtaCte, evento?, observaciones }`.
|
|
75
|
+
- `informarFacturaAceptadaCancelada` se reemplaza por `informarCancelacionTotalFECred({ idCtaCte, formasCancelacion, importeCancelacion })` (la operación anterior no existe).
|
|
76
|
+
- `consultarTiposMotivoRechazo` → `consultarTiposMotivosRechazo`. Los `consultarTipos*` devuelven `{ codigo, descripcion }[]`; `consultarTiposRetenciones` devuelve `{ codigoJurisdiccion, descripcionJurisdiccion, porcentajeRetencion }[]`.
|
|
77
|
+
- Tipos de respuesta según el XSD (`InfoCtaCte`, `Comprobante`, `CuentaCorriente`, ...). `codCtaCte`, CUITs y `codAutorizacion` son `string`. Se eliminan `raw`, `CtaCte`, `ComprobanteFecred`, `RetencionFecred`, `*Item`, `WsFecredError`.
|
|
78
|
+
- `EstadoCtaCte` con los valores reales (`Modificable`, `Aceptada`, `Rechazada`, `CanceladaTotal`, `InformadaAgDpto`); `RolCtaCte`/`EstadoCtaCte` pasan a ser objetos `as const` + tipo literal.
|
|
79
|
+
- Se eliminan los enums inventados `MotivoRechazo`, `FormaCancelacion`, `TipoAjusteOperacion` y `TipoRetencion`: los códigos se obtienen con `consultarTipos*()`.
|
|
80
|
+
- `ENDPOINTS` ya no incluye `wsaa` (usar `WSAA_ENDPOINTS` de common) y `ENDPOINTS.wsfecred.namespace` es `http://ar.gob.afip.wsfecred/FECredService/`.
|
|
81
|
+
- `FecredClient`: recibe `{ token, sign, cuitRepresentada }` (o una función que lo devuelve), valida los parámetros y devuelve respuestas tipadas en lugar de `Record<string, unknown>`.
|
|
82
|
+
- `WsAuth` es `{ token, sign, cuitRepresentada }`.
|
|
83
|
+
- `clearAuthCache()` devuelve `Promise<void>`.
|
|
84
|
+
- Se eliminan `validateCuit` (usar el de common), `validateCodCtaCte`, `validateConsultaCtasCtes` y los re-exports de utilidades de common (`ensureArray`, `parseXml`, `buildXml`, `checkServiceErrors`, `SoapCallOptions`, `WsaaClientConfig`).
|
|
85
|
+
|
|
86
|
+
### Features
|
|
87
|
+
- Nuevas operaciones del WSDL: `consultarObligadoRecepcion`, `consultarCtaCte`, `consultarHistorialEstadosComprobante`, `consultarHistorialEstadosCtaCte`, `obtenerRemitos`, `rechazarNotaDC`, `modificarOpcionTransferencia`, `informarFacturaAgtDptoCltv`, `consultarCuentasEnAgtDptoCltv` y `consultarFacturasAgtDptoCltv`.
|
|
88
|
+
- `aceptarFECred` soporta todos los opcionales del XSD (notas DC, formas de cancelación, retenciones, ajustes, tipo de cancelación, importes, CBU).
|
|
89
|
+
- Todos los métodos aceptan `opts?: CallOptions` (`signal`).
|
|
90
|
+
- Config: `ticketStorage`, `clockOffsetMs`, `autoClockSkew`, `loginErrorCooldownMs`, `tokenTTLMinutes`, `fetch`, `legacyTls`, `wsaa` (cliente propio) y `endpoints` (override).
|
|
91
|
+
- Enums del XSD: `EstadoComprobante`, `TipoFechaFiltro`, `OpcionTransferencia`, `TipoCancelacion`, `TipoAceptacion`, `Resultado`.
|
|
92
|
+
- Validación local según el XSD (CUIT con dígito verificador, fechas, importes con 2 decimales, rangos de punto de venta/número, textos 3..250, CBU) antes de pedir el ticket.
|
|
93
|
+
- Se exportan `ArcaValidationError`, `ArcaTicketVigenteError`, `FileTicketStorage` y `MemoryTicketStorage`.
|
|
94
|
+
|
|
95
|
+
### Fixes
|
|
96
|
+
- Namespace correcto y `SOAPAction` en todas las operaciones (sin él ARCA responde `NullPointerException`); `dummy` con Body vacío.
|
|
97
|
+
- `authRequest` con `token`/`sign`/`cuitRepresentada` (ARCA respondía `wscommon_005`). La CUIT se envía como 11 dígitos.
|
|
98
|
+
- Wrapper `<operacionRequest>` según los elementos del XSD y campos en el orden del XSD (`idCtaCte` anidado, `fecha{tipo,desde,hasta}`, `rolCUITRepresentada`).
|
|
99
|
+
- `obligado` (`S`/`N`) se convertía a boolean con un cast: `'N'` era `true`.
|
|
100
|
+
- Los parsers leían contenedores inexistentes (`arrayCtasCtes`, `tipoComprobante`, ...) y devolvían listas vacías; ahora leen `arrayInfosCtaCte/infoCtaCte`, `arrayComprobantes/comprobante`, `codigoDescripcionReturn/arrayCodigoDescripcion/codigoDescripcion`, etc.
|
|
101
|
+
- Un campo obligatorio ausente en la respuesta lanza error en lugar de devolver `0`/`''`.
|
|
102
|
+
- `arrayErrores` y `arrayErroresFormato` (`codigoDescripcionString`) se lanzan como `ArcaServiceError`; `resultado = 'R'` también.
|
|
103
|
+
- Las operaciones se envían con `kind: 'emision'`: no se reintentan y un error de transporte queda `uncertain`.
|
|
104
|
+
|
|
105
|
+
## 0.2.0 (2026-06-03)
|
|
106
|
+
|
|
107
|
+
- CI con GitHub Actions (Node 18/20/22) y workflow de release por tag.
|
|
108
|
+
- `homepage` apunta a arca-sdk.dev.
|
|
109
|
+
- Lockfile regenerado para resolver `@ramiidv/arca-common` desde npm (el build fallaba en CI).
|
|
110
|
+
|
|
111
|
+
## 0.1.0 (2026-03-31)
|
|
112
|
+
|
|
113
|
+
### Features
|
|
114
|
+
- Initial release
|
|
115
|
+
- Orchestrator class `ArcaFecred` with automatic WSAA authentication
|
|
116
|
+
- Check FCE obligation status (`consultarMontoObligadoRecepcion`)
|
|
117
|
+
- Query current accounts (`consultarCtasCtes`) and invoices (`consultarComprobantes`)
|
|
118
|
+
- Accept (`aceptarFECred`) and reject (`rechazarFECred`) electronic credit invoices
|
|
119
|
+
- Inform accepted FCE cancellation (`informarFacturaAceptadaCancelada`)
|
|
120
|
+
- Parameter queries: retention types, cancellation methods, adjustment types, rejection reasons
|
|
121
|
+
- Input validation with `ArcaValidationError` from `@ramiidv/arca-common`
|
|
122
|
+
- Low-level `FecredClient` for direct SOAP access
|
|
123
|
+
- Enums: `RolCtaCte`, `EstadoCtaCte`, `MotivoRechazo`, `FormaCancelacion`, `TipoAjusteOperacion`, `TipoRetencion`
|
|
124
|
+
- Health check via `status()` / `dummy()`
|
package/README.md
CHANGED
|
@@ -4,347 +4,186 @@
|
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
5
|
[](https://nodejs.org)
|
|
6
6
|
|
|
7
|
-
SDK en TypeScript para el web service **WSFECRED** de **ARCA** (ex AFIP)
|
|
7
|
+
SDK en TypeScript para el web service **WSFECRED** (FECredService) de **ARCA** (ex AFIP): Factura de Crédito Electrónica MiPyME (Ley 27.440).
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Cubre todas las operaciones del WSDL: obligación de recepción, cuentas corrientes, comprobantes, historial de estados, remitos, aceptación, rechazo, cancelación total, rechazo de notas de débito/crédito, opción de transferencia, Agentes de Depósito Colectivo y tablas de parámetros.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
> **0.3.0 es un cambio incompatible**: la versión anterior no funcionaba contra ARCA (namespace, auth y nombres de operaciones incorrectos). Ver [CHANGELOG](./CHANGELOG.md).
|
|
12
|
+
|
|
13
|
+
## Instalación
|
|
12
14
|
|
|
13
15
|
```bash
|
|
14
16
|
npm install @ramiidv/arca-fecred
|
|
15
17
|
```
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
- Certificado digital X.509 y clave privada de ARCA
|
|
21
|
-
- **Testing**: generalo desde [WSASS Homologacion](https://wsass-homo.afip.gob.ar/wsass/portal/main.aspx)
|
|
22
|
-
- **Produccion**: generalo desde [Administracion de Certificados Digitales](https://www.afip.gob.ar/ws/documentacion/certificados.asp) (requiere clave fiscal en [arca.gob.ar](https://arca.gob.ar))
|
|
19
|
+
Requisitos: Node.js >= 18 y un certificado de ARCA con el servicio `wsfecred` autorizado
|
|
20
|
+
([WSASS homologación](https://wsass-homo.afip.gob.ar/wsass/portal/main.aspx) o
|
|
21
|
+
[Administración de Certificados Digitales](https://www.afip.gob.ar/ws/documentacion/certificados.asp) en producción).
|
|
23
22
|
|
|
24
|
-
## Uso
|
|
23
|
+
## Uso rápido
|
|
25
24
|
|
|
26
25
|
```typescript
|
|
27
26
|
import { readFileSync } from 'fs';
|
|
28
|
-
import { ArcaFecred,
|
|
27
|
+
import { ArcaFecred, FileTicketStorage } from '@ramiidv/arca-fecred';
|
|
29
28
|
|
|
30
29
|
const fecred = new ArcaFecred({
|
|
31
30
|
cert: readFileSync('./cert.pem', 'utf-8'),
|
|
32
31
|
key: readFileSync('./key.pem', 'utf-8'),
|
|
33
|
-
cuit: '
|
|
34
|
-
production: false,
|
|
32
|
+
cuit: '20-12345678-6', // CUIT representada (number o string, con o sin guiones)
|
|
33
|
+
production: false,
|
|
34
|
+
ticketStorage: new FileTicketStorage('./.arca-tickets'),
|
|
35
35
|
});
|
|
36
36
|
|
|
37
|
-
//
|
|
38
|
-
const obligado = await fecred.consultarMontoObligadoRecepcion(
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
// Consultar cuentas corrientes como receptor
|
|
42
|
-
const cuentas = await fecred.consultarCtasCtes({
|
|
43
|
-
rol: RolCtaCte.RECEPTOR,
|
|
44
|
-
fechaDesde: '2026-01-01',
|
|
45
|
-
fechaHasta: '2026-03-31',
|
|
37
|
+
// ¿La CUIT receptora está obligada a recibir FCE?
|
|
38
|
+
const { obligado, montoDesde } = await fecred.consultarMontoObligadoRecepcion({
|
|
39
|
+
cuitConsultada: '30712345671',
|
|
40
|
+
fechaEmision: '2026-11-01',
|
|
46
41
|
});
|
|
47
42
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
// Aceptar una FCE
|
|
53
|
-
const aceptar = await fecred.aceptarFECred(12345);
|
|
54
|
-
console.log(aceptar.resultado);
|
|
55
|
-
|
|
56
|
-
// Rechazar una FCE
|
|
57
|
-
const rechazar = await fecred.rechazarFECred(12345, MotivoRechazo.CBU_INCORRECTO);
|
|
58
|
-
console.log(rechazar.resultado);
|
|
59
|
-
|
|
60
|
-
// Informar que una FCE aceptada fue pagada
|
|
61
|
-
const cancelar = await fecred.informarFacturaAceptadaCancelada({
|
|
62
|
-
codCtaCte: 12345,
|
|
63
|
-
codFormaCancelacion: FormaCancelacion.TRANSFERENCIA,
|
|
43
|
+
// Cuentas corrientes recibidas en octubre (paginado)
|
|
44
|
+
const { ctasCtes, hayMas } = await fecred.consultarCtasCtes({
|
|
45
|
+
rol: 'Receptor',
|
|
46
|
+
fecha: { tipo: 'Emision', desde: '2026-10-01', hasta: '2026-10-31' },
|
|
64
47
|
});
|
|
65
|
-
console.log(cancelar.resultado);
|
|
66
|
-
```
|
|
67
48
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
cuit: '20123456789', // CUIT representada
|
|
75
|
-
production: false, // Default: false (testing/homologacion)
|
|
76
|
-
timeout: 30_000, // Default: 30000 (30 segundos)
|
|
77
|
-
retries: 1, // Default: 1 (reintentos en errores transitorios)
|
|
78
|
-
retryDelayMs: 1_000, // Default: 1000 (backoff exponencial: 1s, 2s, ...)
|
|
79
|
-
onEvent: (e) => { // Opcional: callback para logging/debugging
|
|
80
|
-
console.log(e.type, e);
|
|
81
|
-
},
|
|
82
|
-
});
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
## Ejemplos
|
|
86
|
-
|
|
87
|
-
### Verificar obligacion de recepcion FCE
|
|
88
|
-
|
|
89
|
-
```typescript
|
|
90
|
-
const resultado = await fecred.consultarMontoObligadoRecepcion('30712345678');
|
|
91
|
-
|
|
92
|
-
if (resultado.obligado) {
|
|
93
|
-
console.log(`CUIT obligada a recibir FCE desde $${resultado.montoDesde}`);
|
|
94
|
-
} else {
|
|
95
|
-
console.log('CUIT no obligada a recibir FCE');
|
|
96
|
-
}
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
### Consultar cuentas corrientes
|
|
100
|
-
|
|
101
|
-
```typescript
|
|
102
|
-
// Como emisor (mis facturas FCE emitidas)
|
|
103
|
-
const misEmitidas = await fecred.consultarCtasCtes({
|
|
104
|
-
rol: RolCtaCte.EMISOR,
|
|
105
|
-
fechaDesde: '2026-01-01',
|
|
106
|
-
fechaHasta: '2026-03-31',
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
// Como receptor (FCE que me enviaron)
|
|
110
|
-
const recibidas = await fecred.consultarCtasCtes({
|
|
111
|
-
rol: RolCtaCte.RECEPTOR,
|
|
112
|
-
cuitEmisor: '30712345678', // opcional: filtrar por emisor
|
|
113
|
-
fechaDesde: '2026-01-01',
|
|
114
|
-
fechaHasta: '2026-03-31',
|
|
115
|
-
});
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
### Consultar comprobantes FCE
|
|
119
|
-
|
|
120
|
-
```typescript
|
|
121
|
-
// Buscar por CUIT emisor
|
|
122
|
-
const comprobantes = await fecred.consultarComprobantes({
|
|
123
|
-
cuitEmisor: '30712345678',
|
|
124
|
-
fechaDesde: '2026-01-01',
|
|
125
|
-
fechaHasta: '2026-03-31',
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
// Buscar un comprobante especifico por codigo de cuenta corriente
|
|
129
|
-
const comprobante = await fecred.consultarComprobantes({
|
|
130
|
-
codCtaCte: 12345,
|
|
131
|
-
});
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
### Aceptar y luego informar cancelacion
|
|
135
|
-
|
|
136
|
-
```typescript
|
|
137
|
-
import { FormaCancelacion } from '@ramiidv/arca-fecred';
|
|
138
|
-
|
|
139
|
-
// 1. Aceptar la FCE
|
|
140
|
-
await fecred.aceptarFECred(12345);
|
|
141
|
-
|
|
142
|
-
// 2. Luego de pagar, informar la cancelacion
|
|
143
|
-
await fecred.informarFacturaAceptadaCancelada({
|
|
144
|
-
codCtaCte: 12345,
|
|
145
|
-
codFormaCancelacion: FormaCancelacion.TRANSFERENCIA,
|
|
146
|
-
observaciones: 'Transferencia realizada el 2026-03-15',
|
|
49
|
+
// Aceptar una FCE
|
|
50
|
+
const r = await fecred.aceptarFECred({
|
|
51
|
+
idCtaCte: { codCtaCte: ctasCtes[0].codCtaCte },
|
|
52
|
+
saldoAceptado: ctasCtes[0].saldo,
|
|
53
|
+
codMoneda: ctasCtes[0].codMoneda,
|
|
54
|
+
cotizacionMonedaUlt: 1,
|
|
147
55
|
});
|
|
56
|
+
console.log(r.resultado); // 'A' o 'O' (un rechazo se lanza como ArcaServiceError)
|
|
148
57
|
```
|
|
149
58
|
|
|
150
|
-
|
|
59
|
+
## Configuración
|
|
60
|
+
|
|
61
|
+
`ArcaFecredConfig` extiende `ArcaBaseConfig` de `@ramiidv/arca-common`:
|
|
62
|
+
|
|
63
|
+
| Opción | Tipo | Default | Descripción |
|
|
64
|
+
| -------------------------------------------------------- | ------------------------------- | ------------------ | ----------------------------------------------------------------------------- |
|
|
65
|
+
| `cert`, `key` | `string` | — | Certificado y clave privada (PEM) |
|
|
66
|
+
| `cuit` | `number \| string` | — | CUIT representada; se valida el dígito verificador y se envía como 11 dígitos |
|
|
67
|
+
| `production` | `boolean` | `false` | Homologación o producción |
|
|
68
|
+
| `timeout` | `number` | `30000` | Timeout HTTP (ms) |
|
|
69
|
+
| `retries` / `retryDelayMs` | `number` | `1` / `1000` | Reintentos de **consultas** (las operaciones nunca se reintentan) |
|
|
70
|
+
| `tokenTTLMinutes` | `number` | `720` | Vigencia pedida a WSAA |
|
|
71
|
+
| `ticketStorage` | `TicketStorage` | — | Persistencia del TA (recomendado en producción: `FileTicketStorage` o propio) |
|
|
72
|
+
| `clockOffsetMs`, `autoClockSkew`, `loginErrorCooldownMs` | | | Opciones de WSAA (ver arca-common) |
|
|
73
|
+
| `fetch` | `typeof fetch` | `globalThis.fetch` | `fetch` propio (proxy, tests) |
|
|
74
|
+
| `legacyTls` | `'auto' \| 'never' \| 'always'` | `'auto'` | Transporte TLS legacy |
|
|
75
|
+
| `onEvent` | `(e: ArcaEvent) => void` | — | Eventos `auth:*` y `request:*` |
|
|
76
|
+
| `wsaa` | `WsaaClient` | — | `WsaaClient` propio (compartir tickets entre SDKs) |
|
|
77
|
+
| `endpoints` | `{ wsfecred?, wsaa? }` | — | Sobrescribe las URLs |
|
|
78
|
+
|
|
79
|
+
Todos los métodos aceptan un último parámetro opcional `opts?: CallOptions` (`{ signal }`) para cancelar.
|
|
80
|
+
|
|
81
|
+
## Operaciones
|
|
82
|
+
|
|
83
|
+
Fuente: WSDL de FECredService (`https://fwshomo.afip.gob.ar/wsfecred/FECredService?wsdl`). Los nombres de campos siguen el XSD.
|
|
84
|
+
|
|
85
|
+
### Consultas (se reintentan ante errores transitorios)
|
|
86
|
+
|
|
87
|
+
| Método | Operación | Devuelve |
|
|
88
|
+
| -------------------------------------------------------------------------------------------------------------------------- | --------- | ------------------------------------------------------------------------ |
|
|
89
|
+
| `status()` | `dummy` | `{ appserver, dbserver, authserver }` |
|
|
90
|
+
| `consultarMontoObligadoRecepcion({ cuitConsultada, fechaEmision })` | idem | `{ obligado, montoDesde?, evento?, observaciones }` |
|
|
91
|
+
| `consultarObligadoRecepcion(cuit)` | idem | `{ obligado, desde?, ... }` (campo `respuesta` del WS) |
|
|
92
|
+
| `consultarCtasCtes({ rol, cuitContraparte?, fecha?, estadoCtaCte?, nroPagina?, opcionTransferencia? })` | idem | `{ ctasCtes: InfoCtaCte[], nroPagina?, hayMas?, ... }` |
|
|
93
|
+
| `consultarCtaCte(idCtaCte)` | idem | `{ ctaCte: CuentaCorriente, ... }` |
|
|
94
|
+
| `consultarComprobantes({ rol, cuitContraparte?, codTipoCmp?, estadoCmp?, fecha?, codCtaCte?, estadoCtaCte?, nroPagina? })` | idem | `{ comprobantes: Comprobante[], nroPagina?, hayMas?, ... }` |
|
|
95
|
+
| `consultarHistorialEstadosComprobante(idComprobante)` | idem | `{ idComprobante, estados }` |
|
|
96
|
+
| `consultarHistorialEstadosCtaCte(idCtaCte)` | idem | `{ idCtaCte, estados }` |
|
|
97
|
+
| `obtenerRemitos(idComprobante)` | idem | `IdComprobante[]` |
|
|
98
|
+
| `consultarCuentasEnAgtDptoCltv()` | idem | `{ cuentas, ... }` |
|
|
99
|
+
| `consultarFacturasAgtDptoCltv({ idCtaCte?, fecha? })` | idem | `{ facturas, ... }` |
|
|
100
|
+
| `consultarTiposRetenciones()` | idem | `{ codigoJurisdiccion, descripcionJurisdiccion, porcentajeRetencion }[]` |
|
|
101
|
+
| `consultarTiposFormasCancelacion()` | idem | `{ codigo, descripcion }[]` |
|
|
102
|
+
| `consultarTiposMotivosRechazo()` | idem | `{ codigo, descripcion }[]` |
|
|
103
|
+
| `consultarTiposAjustesOperacion()` | idem | `{ codigo, descripcion }[]` |
|
|
104
|
+
|
|
105
|
+
### Operaciones que cambian estado (emisiones: nunca se reintentan)
|
|
106
|
+
|
|
107
|
+
| Método | Operación | Devuelve |
|
|
108
|
+
| ------------------------------------------------------------------------------------- | --------- | ------------------------------------------------------------- |
|
|
109
|
+
| `aceptarFECred({ idCtaCte, saldoAceptado, codMoneda, cotizacionMonedaUlt, ... })` | idem | `{ resultado: 'A' \| 'O', idCtaCte, evento?, observaciones }` |
|
|
110
|
+
| `rechazarFECred({ idCtaCte, motivos })` | idem | idem |
|
|
111
|
+
| `informarCancelacionTotalFECred({ idCtaCte, formasCancelacion, importeCancelacion })` | idem | idem |
|
|
112
|
+
| `modificarOpcionTransferencia({ idCtaCte, opcionTransferencia })` | idem | idem |
|
|
113
|
+
| `informarFacturaAgtDptoCltv({ idCtaCte, ctaAgente })` | idem | idem |
|
|
114
|
+
| `rechazarNotaDC({ idComprobante, motivos })` | idem | `{ resultado, idComprobante, ... }` |
|
|
115
|
+
|
|
116
|
+
`aceptarFECred` acepta además los opcionales del XSD: `confirmarNotasDC` (`{ acepta, idNota }[]`), `formasCancelacion`, `retenciones` (`{ codTipo, importe, porcentaje, descMotivo? }[]`), `ajustesOperacion` (`{ codigo, importe }[]`), `tipoCancelacion` (`'PAR' | 'TOT'`), `importeCancelado`, `importeTotalRetPesos`, `importeEmbargoPesos`, `informaCBU` y `cbuComprador`.
|
|
117
|
+
|
|
118
|
+
### Identificadores
|
|
151
119
|
|
|
152
120
|
```typescript
|
|
153
|
-
|
|
121
|
+
// IdCtaCteType es un xsd:choice: por código de cuenta corriente o por factura
|
|
122
|
+
const porCodigo = { codCtaCte: '1234567890' };
|
|
123
|
+
const porFactura = { idFactura: { cuitEmisor: '30712345671', codTipoCmp: 201, ptoVta: 3, nroCmp: 125 } };
|
|
154
124
|
|
|
155
|
-
await fecred.
|
|
125
|
+
await fecred.consultarCtaCte(porFactura);
|
|
156
126
|
```
|
|
157
127
|
|
|
158
|
-
|
|
128
|
+
Las respuestas devuelven `codCtaCte`, CUITs y `codAutorizacion` (CAE) como **string**; importes como `number`; fechas como el string que envía ARCA; los `S`/`N` como `boolean`.
|
|
159
129
|
|
|
160
|
-
|
|
161
|
-
// Tipos de retencion
|
|
162
|
-
const retenciones = await fecred.consultarTiposRetenciones();
|
|
163
|
-
for (const r of retenciones) {
|
|
164
|
-
console.log(`${r.codTipoRetencion}: ${r.descTipoRetencion}`);
|
|
165
|
-
}
|
|
130
|
+
### Paginado
|
|
166
131
|
|
|
167
|
-
|
|
168
|
-
const formas = await fecred.consultarTiposFormasCancelacion();
|
|
132
|
+
`consultarCtasCtes` y `consultarComprobantes` devuelven `nroPagina` y `hayMas`. Pedí la página siguiente con `nroPagina`.
|
|
169
133
|
|
|
170
|
-
|
|
171
|
-
const ajustes = await fecred.consultarTiposAjustesOperacion();
|
|
134
|
+
### Tablas de códigos
|
|
172
135
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
```
|
|
136
|
+
Los códigos de formas de cancelación, motivos de rechazo, ajustes de operación y retenciones **no están en el WSDL**: obtenelos con `consultarTipos*()`. El SDK solo exporta las enumeraciones definidas en el XSD:
|
|
137
|
+
`RolCtaCte`, `EstadoCtaCte` (`Modificable`, `Aceptada`, `Rechazada`, `CanceladaTotal`, `InformadaAgDpto`), `EstadoComprobante`, `TipoFechaFiltro`, `OpcionTransferencia` (`SCA`, `ADC`), `TipoCancelacion` (`PAR`, `TOT`), `TipoAceptacion` y `Resultado`. Se pueden usar como `RolCtaCte.RECEPTOR` o con el literal (`'Receptor'`).
|
|
176
138
|
|
|
177
|
-
|
|
139
|
+
## Errores
|
|
178
140
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
141
|
+
| Clase | Cuándo |
|
|
142
|
+
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
143
|
+
| `ArcaValidationError` | Datos inválidos (CUIT con dígito verificador incorrecto, fechas inexistentes, importes NaN/negativos, textos fuera de 3..250, CBU inválido, etc.). No se llega a pedir el ticket ni a llamar a ARCA. `field` indica el parámetro. |
|
|
144
|
+
| `ArcaServiceError` | ARCA devolvió `arrayErrores` o `arrayErroresFormato`, o una operación terminó con `resultado = 'R'`. `errors: { code, msg, rawCode? }[]` (`rawCode` para los códigos alfanuméricos de `arrayErroresFormato`). |
|
|
145
|
+
| `ArcaSoapError` | HTTP, timeout, SOAP Fault (ej: `wscommon_005`/`wscommon_007` de auth) o respuesta sin un campo obligatorio del XSD. `uncertain` indica si ARCA pudo haber procesado el request. |
|
|
146
|
+
| `ArcaAuthError` / `ArcaTicketVigenteError` | Falla de WSAA / ya hay un TA vigente que no está en el `ticketStorage`. |
|
|
185
147
|
|
|
186
|
-
|
|
148
|
+
Las observaciones (`arrayObservaciones`) y el `evento` no son errores: vienen en el resultado.
|
|
187
149
|
|
|
188
|
-
|
|
150
|
+
### Resultado incierto en operaciones
|
|
189
151
|
|
|
190
|
-
|
|
191
|
-
- **Configurable**: `retries: 0` para desactivar, `retries: 3` para mas intentos
|
|
152
|
+
Las emisiones (`aceptarFECred`, `rechazarFECred`, `informarCancelacionTotalFECred`, `rechazarNotaDC`, `modificarOpcionTransferencia`, `informarFacturaAgtDptoCltv`) se envían una sola vez. Si la respuesta se pierde (timeout, conexión cortada, HTTP 5xx, respuesta ilegible) se lanza `ArcaSoapError` con `uncertain = true`: la operación **pudo haberse registrado**. Antes de reintentar, consultá el estado:
|
|
192
153
|
|
|
193
154
|
```typescript
|
|
194
|
-
const fecred = new ArcaFecred({
|
|
195
|
-
...config,
|
|
196
|
-
retries: 2, // 2 reintentos (3 intentos totales)
|
|
197
|
-
retryDelayMs: 2000, // empezar con 2s -> 4s -> 8s
|
|
198
|
-
});
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
## Eventos / Logging
|
|
202
|
-
|
|
203
|
-
El SDK emite eventos para debugging y monitoreo sin forzar un logger especifico.
|
|
204
|
-
|
|
205
|
-
```typescript
|
|
206
|
-
const fecred = new ArcaFecred({
|
|
207
|
-
...config,
|
|
208
|
-
onEvent: (e) => console.log(`[${e.type}]`, e),
|
|
209
|
-
});
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
| Evento | Cuando | Datos |
|
|
213
|
-
| --- | --- | --- |
|
|
214
|
-
| `auth:login` | Nuevo token obtenido | `service`, `durationMs` |
|
|
215
|
-
| `auth:cache-hit` | Token cacheado reutilizado | `service` |
|
|
216
|
-
| `request:start` | Antes de una llamada SOAP | `method`, `endpoint` |
|
|
217
|
-
| `request:end` | Llamada SOAP completada | `method`, `durationMs` |
|
|
218
|
-
| `request:retry` | Reintentando tras error | `method`, `attempt`, `error` |
|
|
219
|
-
| `request:error` | Llamada SOAP fallo | `method`, `error` |
|
|
220
|
-
|
|
221
|
-
## Manejo de errores
|
|
222
|
-
|
|
223
|
-
El SDK provee clases de error especificas para catch granular:
|
|
224
|
-
|
|
225
|
-
```typescript
|
|
226
|
-
import {
|
|
227
|
-
ArcaFecred,
|
|
228
|
-
ArcaAuthError,
|
|
229
|
-
ArcaServiceError,
|
|
230
|
-
ArcaSoapError,
|
|
231
|
-
} from '@ramiidv/arca-fecred';
|
|
232
|
-
|
|
233
155
|
try {
|
|
234
|
-
|
|
156
|
+
await fecred.aceptarFECred(params);
|
|
235
157
|
} catch (e) {
|
|
236
|
-
if (e instanceof
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
if (e instanceof ArcaServiceError) {
|
|
243
|
-
// Error de negocio de WSFECRED (FCE no encontrada, estado invalido, etc.)
|
|
244
|
-
for (const err of e.errors) {
|
|
245
|
-
console.error(`[${err.code}] ${err.msg}`);
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
if (e instanceof ArcaSoapError) {
|
|
250
|
-
// Error HTTP/SOAP (timeout, servidor caido, etc.)
|
|
251
|
-
console.error('HTTP status:', e.statusCode);
|
|
158
|
+
if (e instanceof ArcaSoapError && e.uncertain) {
|
|
159
|
+
const { estados } = await fecred.consultarHistorialEstadosCtaCte(params.idCtaCte);
|
|
160
|
+
// o consultarCtaCte(params.idCtaCte) → ctaCte.estadoCtaCte.estado
|
|
161
|
+
// Si ya figura Aceptada/Rechazada, no reintentar.
|
|
252
162
|
}
|
|
163
|
+
throw e;
|
|
253
164
|
}
|
|
254
165
|
```
|
|
255
166
|
|
|
256
|
-
|
|
257
|
-
| --- | --- |
|
|
258
|
-
| `ArcaAuthError` | Falla en login WSAA, respuesta inesperada, token/sign invalidos |
|
|
259
|
-
| `ArcaServiceError` | Error devuelto por WSFECRED (FCE no encontrada, operacion invalida, etc.). Contiene `errors: { code, msg }[]` |
|
|
260
|
-
| `ArcaSoapError` | Error HTTP, timeout, SOAP Fault. Contiene `statusCode?: number` |
|
|
261
|
-
| `ArcaError` | Clase base para todos los errores del SDK |
|
|
262
|
-
|
|
263
|
-
## API
|
|
264
|
-
|
|
265
|
-
### `new ArcaFecred(config)`
|
|
266
|
-
|
|
267
|
-
| Parametro | Tipo | Default | Descripcion |
|
|
268
|
-
| --- | --- | --- | --- |
|
|
269
|
-
| `cert` | `string` | -- | Contenido del certificado X.509 (PEM) |
|
|
270
|
-
| `key` | `string` | -- | Contenido de la clave privada (PEM) |
|
|
271
|
-
| `cuit` | `string` | -- | CUIT de la entidad representada |
|
|
272
|
-
| `production` | `boolean` | `false` | Entorno de produccion |
|
|
273
|
-
| `timeout` | `number` | `30000` | Timeout HTTP en milisegundos |
|
|
274
|
-
| `retries` | `number` | `1` | Reintentos en errores transitorios |
|
|
275
|
-
| `retryDelayMs` | `number` | `1000` | Delay inicial entre reintentos (exponencial) |
|
|
276
|
-
| `onEvent` | `function` | -- | Callback para eventos del SDK |
|
|
277
|
-
|
|
278
|
-
### Consultas de operaciones
|
|
279
|
-
|
|
280
|
-
| Metodo | Descripcion |
|
|
281
|
-
| --- | --- |
|
|
282
|
-
| `consultarMontoObligadoRecepcion(cuit)` | Verifica si una CUIT esta obligada a recibir FCE |
|
|
283
|
-
| `consultarCtasCtes(params)` | Consulta cuentas corrientes de actividad FCE |
|
|
284
|
-
| `consultarComprobantes(params)` | Busca comprobantes FCE por filtros |
|
|
285
|
-
|
|
286
|
-
### Acciones sobre FCE
|
|
167
|
+
## Cliente de bajo nivel
|
|
287
168
|
|
|
288
|
-
|
|
289
|
-
| --- | --- |
|
|
290
|
-
| `aceptarFECred(codCtaCte)` | Acepta una FCE |
|
|
291
|
-
| `rechazarFECred(codCtaCte, codMotivoRechazo)` | Rechaza una FCE con motivo |
|
|
292
|
-
| `informarFacturaAceptadaCancelada(params)` | Informa que una FCE aceptada fue pagada/cancelada |
|
|
293
|
-
|
|
294
|
-
### Consultas de parametros
|
|
295
|
-
|
|
296
|
-
| Metodo | Descripcion |
|
|
297
|
-
| --- | --- |
|
|
298
|
-
| `consultarTiposRetenciones()` | Tipos de retenciones disponibles |
|
|
299
|
-
| `consultarTiposFormasCancelacion()` | Formas de cancelacion disponibles |
|
|
300
|
-
| `consultarTiposAjustesOperacion()` | Tipos de ajustes de operacion disponibles |
|
|
301
|
-
| `consultarTiposMotivoRechazo()` | Motivos de rechazo disponibles |
|
|
302
|
-
|
|
303
|
-
### Estado y utilidades
|
|
304
|
-
|
|
305
|
-
| Metodo | Descripcion |
|
|
306
|
-
| --- | --- |
|
|
307
|
-
| `status()` | Health check del servicio WSFECRED (no requiere autenticacion) |
|
|
308
|
-
| `clearAuthCache()` | Invalida el ticket de acceso cacheado |
|
|
309
|
-
|
|
310
|
-
### Acceso a clientes de bajo nivel
|
|
311
|
-
|
|
312
|
-
Para casos avanzados, se pueden usar los clientes individuales directamente:
|
|
169
|
+
`fecred.fecred` es un `FecredClient`: los mismos métodos con las credenciales como primer parámetro y respuestas tipadas.
|
|
313
170
|
|
|
314
171
|
```typescript
|
|
315
|
-
const fecred = new ArcaFecred({ /* ... */ });
|
|
316
|
-
|
|
317
|
-
// Obtener ticket de acceso manualmente
|
|
318
172
|
const ticket = await fecred.wsaa.getAccessTicket('wsfecred');
|
|
319
|
-
|
|
320
|
-
const
|
|
321
|
-
Token: ticket.token,
|
|
322
|
-
Sign: ticket.sign,
|
|
323
|
-
Cuit: '20123456789',
|
|
324
|
-
};
|
|
325
|
-
|
|
326
|
-
// Llamar directamente al servicio
|
|
327
|
-
const rawResult = await fecred.fecred.consultarMontoObligadoRecepcion(
|
|
328
|
-
credenciales,
|
|
329
|
-
'30712345678',
|
|
330
|
-
);
|
|
173
|
+
const auth = { token: ticket.token, sign: ticket.sign, cuitRepresentada: '20123456786' };
|
|
174
|
+
const tipos = await fecred.client.consultarTiposMotivosRechazo(auth);
|
|
331
175
|
```
|
|
332
176
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
- `RolCtaCte` -- Rol en la cuenta corriente (EMISOR, RECEPTOR)
|
|
336
|
-
- `EstadoCtaCte` -- Estado de la cuenta corriente (PENDIENTE_ACEPTACION, ACEPTADA, RECHAZADA, CANCELADA, ANULADA)
|
|
337
|
-
- `MotivoRechazo` -- Motivos de rechazo (NOTA_CREDITO_DEBITO, CUIT_INCORRECTO, FECHA_INCORRECTA, CBU_INCORRECTO, OTROS)
|
|
338
|
-
- `FormaCancelacion` -- Formas de cancelacion (ACREDITACION_CUENTA, TRANSFERENCIA, CHEQUE, PAGO_ELECTRONICO, COMPENSACION, ENDOSO, OTRO)
|
|
339
|
-
- `TipoAjusteOperacion` -- Tipos de ajuste (NOTA_CREDITO, NOTA_DEBITO)
|
|
340
|
-
- `TipoRetencion` -- Tipos de retencion (GANANCIAS, IVA, SUSS, INGRESOS_BRUTOS, OTRAS)
|
|
177
|
+
Detalles del protocolo (verificados contra homologación): namespace `http://ar.gob.afip.wsfecred/FECredService/`, wrapper `<operacionRequest>`, header `SOAPAction` = namespace + operación (obligatorio), `dummy` con Body vacío.
|
|
341
178
|
|
|
342
179
|
## Entornos
|
|
343
180
|
|
|
344
|
-
| Entorno
|
|
345
|
-
|
|
|
346
|
-
|
|
|
347
|
-
|
|
|
181
|
+
| Entorno | WSFECRED |
|
|
182
|
+
| ------------ | ---------------------------------------------------------- |
|
|
183
|
+
| Homologación | `https://fwshomo.afip.gob.ar/wsfecred/FECredService` |
|
|
184
|
+
| Producción | `https://serviciosjava.afip.gob.ar/wsfecred/FECredService` |
|
|
185
|
+
|
|
186
|
+
Los endpoints de WSAA están en `WSAA_ENDPOINTS` de `@ramiidv/arca-common`.
|
|
348
187
|
|
|
349
188
|
## Licencia
|
|
350
189
|
|