@ramiidv/arca-sdk 0.1.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 +21 -0
- package/README.md +273 -0
- package/dist/arca.d.ts +101 -0
- package/dist/arca.d.ts.map +1 -0
- package/dist/arca.js +199 -0
- package/dist/arca.js.map +1 -0
- package/dist/constants.d.ts +111 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +157 -0
- package/dist/constants.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/soap-client.d.ts +19 -0
- package/dist/soap-client.d.ts.map +1 -0
- package/dist/soap-client.js +99 -0
- package/dist/soap-client.js.map +1 -0
- package/dist/types.d.ts +228 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/wsaa.d.ts +37 -0
- package/dist/wsaa.d.ts.map +1 -0
- package/dist/wsaa.js +128 -0
- package/dist/wsaa.js.map +1 -0
- package/dist/wsfe.d.ts +59 -0
- package/dist/wsfe.d.ts.map +1 -0
- package/dist/wsfe.js +238 -0
- package/dist/wsfe.js.map +1 -0
- package/package.json +60 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,gBAAgB;AAChB,+DAA+D"}
|
package/dist/wsaa.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { AccessTicket } from "./types.js";
|
|
2
|
+
export declare class WsaaClient {
|
|
3
|
+
private cert;
|
|
4
|
+
private key;
|
|
5
|
+
private production;
|
|
6
|
+
private tokenTTLMinutes;
|
|
7
|
+
private ticketCache;
|
|
8
|
+
constructor(opts: {
|
|
9
|
+
cert: string;
|
|
10
|
+
key: string;
|
|
11
|
+
production: boolean;
|
|
12
|
+
tokenTTLMinutes: number;
|
|
13
|
+
});
|
|
14
|
+
/**
|
|
15
|
+
* Obtiene un Ticket de Acceso (TA) para el servicio indicado.
|
|
16
|
+
* Cachea el ticket y lo reutiliza si no expiró.
|
|
17
|
+
*/
|
|
18
|
+
getAccessTicket(service: string): Promise<AccessTicket>;
|
|
19
|
+
/**
|
|
20
|
+
* Invalida el ticket cacheado para un servicio.
|
|
21
|
+
*/
|
|
22
|
+
clearTicket(service: string): void;
|
|
23
|
+
/**
|
|
24
|
+
* Crea el Ticket de Requerimiento de Acceso (TRA) XML.
|
|
25
|
+
*/
|
|
26
|
+
private createTRA;
|
|
27
|
+
/**
|
|
28
|
+
* Firma el TRA con CMS/PKCS#7 usando el certificado y la clave privada.
|
|
29
|
+
* Retorna el CMS en base64.
|
|
30
|
+
*/
|
|
31
|
+
private signTRA;
|
|
32
|
+
/**
|
|
33
|
+
* Envía el CMS al endpoint loginCms de WSAA y parsea el Ticket de Acceso.
|
|
34
|
+
*/
|
|
35
|
+
private loginCms;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=wsaa.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wsaa.d.ts","sourceRoot":"","sources":["../src/wsaa.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG/C,qBAAa,UAAU;IACrB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,UAAU,CAAU;IAC5B,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,WAAW,CAAwC;gBAE/C,IAAI,EAAE;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,GAAG,EAAE,MAAM,CAAC;QACZ,UAAU,EAAE,OAAO,CAAC;QACpB,eAAe,EAAE,MAAM,CAAC;KACzB;IAOD;;;OAGG;IACG,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAc7D;;OAEG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIlC;;OAEG;IACH,OAAO,CAAC,SAAS;IAuBjB;;;OAGG;IACH,OAAO,CAAC,OAAO;IAgCf;;OAEG;YACW,QAAQ;CAuDvB"}
|
package/dist/wsaa.js
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import forge from "node-forge";
|
|
2
|
+
import { ENDPOINTS, WSAA_NAMESPACE } from "./constants.js";
|
|
3
|
+
import { soapCall, parseXml, buildXml } from "./soap-client.js";
|
|
4
|
+
export class WsaaClient {
|
|
5
|
+
cert;
|
|
6
|
+
key;
|
|
7
|
+
production;
|
|
8
|
+
tokenTTLMinutes;
|
|
9
|
+
ticketCache = new Map();
|
|
10
|
+
constructor(opts) {
|
|
11
|
+
this.cert = opts.cert;
|
|
12
|
+
this.key = opts.key;
|
|
13
|
+
this.production = opts.production;
|
|
14
|
+
this.tokenTTLMinutes = opts.tokenTTLMinutes;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Obtiene un Ticket de Acceso (TA) para el servicio indicado.
|
|
18
|
+
* Cachea el ticket y lo reutiliza si no expiró.
|
|
19
|
+
*/
|
|
20
|
+
async getAccessTicket(service) {
|
|
21
|
+
const cached = this.ticketCache.get(service);
|
|
22
|
+
if (cached && cached.expirationTime > new Date()) {
|
|
23
|
+
return cached;
|
|
24
|
+
}
|
|
25
|
+
const tra = this.createTRA(service);
|
|
26
|
+
const cms = this.signTRA(tra);
|
|
27
|
+
const ticket = await this.loginCms(cms);
|
|
28
|
+
this.ticketCache.set(service, ticket);
|
|
29
|
+
return ticket;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Invalida el ticket cacheado para un servicio.
|
|
33
|
+
*/
|
|
34
|
+
clearTicket(service) {
|
|
35
|
+
this.ticketCache.delete(service);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Crea el Ticket de Requerimiento de Acceso (TRA) XML.
|
|
39
|
+
*/
|
|
40
|
+
createTRA(service) {
|
|
41
|
+
const now = new Date();
|
|
42
|
+
const uniqueId = Math.floor(now.getTime() / 1000);
|
|
43
|
+
const generationTime = new Date(now.getTime() - 120_000).toISOString();
|
|
44
|
+
const expirationTime = new Date(now.getTime() + this.tokenTTLMinutes * 60_000).toISOString();
|
|
45
|
+
const tra = {
|
|
46
|
+
loginTicketRequest: {
|
|
47
|
+
"@_version": "1.0",
|
|
48
|
+
header: {
|
|
49
|
+
uniqueId: uniqueId,
|
|
50
|
+
generationTime: generationTime,
|
|
51
|
+
expirationTime: expirationTime,
|
|
52
|
+
},
|
|
53
|
+
service: service,
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
return '<?xml version="1.0" encoding="UTF-8"?>\n' + buildXml(tra);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Firma el TRA con CMS/PKCS#7 usando el certificado y la clave privada.
|
|
60
|
+
* Retorna el CMS en base64.
|
|
61
|
+
*/
|
|
62
|
+
signTRA(traXml) {
|
|
63
|
+
const cert = forge.pki.certificateFromPem(this.cert);
|
|
64
|
+
const privateKey = forge.pki.privateKeyFromPem(this.key);
|
|
65
|
+
const p7 = forge.pkcs7.createSignedData();
|
|
66
|
+
p7.content = forge.util.createBuffer(traXml, "utf8");
|
|
67
|
+
p7.addCertificate(cert);
|
|
68
|
+
p7.addSigner({
|
|
69
|
+
key: privateKey,
|
|
70
|
+
certificate: cert,
|
|
71
|
+
digestAlgorithm: forge.pki.oids.sha256,
|
|
72
|
+
authenticatedAttributes: [
|
|
73
|
+
{
|
|
74
|
+
type: forge.pki.oids.contentType,
|
|
75
|
+
value: forge.pki.oids.data,
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
type: forge.pki.oids.messageDigest,
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
type: forge.pki.oids.signingTime,
|
|
82
|
+
value: new Date(),
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
});
|
|
86
|
+
p7.sign();
|
|
87
|
+
const asn1 = p7.toAsn1();
|
|
88
|
+
const der = forge.asn1.toDer(asn1);
|
|
89
|
+
return forge.util.encode64(der.getBytes());
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Envía el CMS al endpoint loginCms de WSAA y parsea el Ticket de Acceso.
|
|
93
|
+
*/
|
|
94
|
+
async loginCms(cmsBase64) {
|
|
95
|
+
const endpoint = this.production
|
|
96
|
+
? ENDPOINTS.wsaa.production
|
|
97
|
+
: ENDPOINTS.wsaa.testing;
|
|
98
|
+
const soapBody = `<loginCms xmlns="${WSAA_NAMESPACE}"><in0>${cmsBase64}</in0></loginCms>`;
|
|
99
|
+
const responseXml = await soapCall(endpoint, soapBody, "loginCms");
|
|
100
|
+
const parsed = parseXml(responseXml);
|
|
101
|
+
// Navegar la estructura del response SOAP
|
|
102
|
+
const envelope = parsed["soapenv:Envelope"] ||
|
|
103
|
+
parsed["soap:Envelope"] ||
|
|
104
|
+
parsed["S:Envelope"];
|
|
105
|
+
const body = envelope?.["soapenv:Body"] ||
|
|
106
|
+
envelope?.["soap:Body"] ||
|
|
107
|
+
envelope?.["S:Body"];
|
|
108
|
+
const loginResponse = body?.loginCmsResponse || body?.["ns2:loginCmsResponse"];
|
|
109
|
+
const loginReturn = loginResponse?.loginCmsReturn || loginResponse?.["ns2:loginCmsReturn"];
|
|
110
|
+
if (!loginReturn) {
|
|
111
|
+
throw new Error(`WSAA: respuesta inesperada del servidor.\n${responseXml}`);
|
|
112
|
+
}
|
|
113
|
+
// loginReturn es un XML string embebido, parsearlo
|
|
114
|
+
const taXml = parseXml(loginReturn);
|
|
115
|
+
const credentials = taXml.loginTicketResponse?.credentials ||
|
|
116
|
+
taXml?.loginTicketResponse?.header;
|
|
117
|
+
const token = taXml.loginTicketResponse?.credentials?.token ?? credentials?.token;
|
|
118
|
+
const sign = taXml.loginTicketResponse?.credentials?.sign ?? credentials?.sign;
|
|
119
|
+
if (!token || !sign) {
|
|
120
|
+
throw new Error(`WSAA: no se pudo obtener token/sign de la respuesta.\n${loginReturn}`);
|
|
121
|
+
}
|
|
122
|
+
const headerExp = taXml.loginTicketResponse?.header?.expirationTime ??
|
|
123
|
+
credentials?.expirationTime;
|
|
124
|
+
const expirationTime = headerExp ? new Date(headerExp) : new Date(Date.now() + this.tokenTTLMinutes * 60_000);
|
|
125
|
+
return { token, sign, expirationTime };
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=wsaa.js.map
|
package/dist/wsaa.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wsaa.js","sourceRoot":"","sources":["../src/wsaa.ts"],"names":[],"mappings":"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"}
|
package/dist/wsfe.d.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { WsfeAuth, InvoiceRequest, FECAESolicitarResult, FECompConsultarResult, ServerStatus, ParamItem, MonedaItem, PtoVentaItem, CotizacionResult } from "./types.js";
|
|
2
|
+
export declare class WsfeClient {
|
|
3
|
+
private endpoint;
|
|
4
|
+
constructor(production: boolean);
|
|
5
|
+
/**
|
|
6
|
+
* Solicita CAE (Código de Autorización Electrónica) para uno o más comprobantes.
|
|
7
|
+
*/
|
|
8
|
+
solicitarCAE(auth: WsfeAuth, request: InvoiceRequest): Promise<FECAESolicitarResult>;
|
|
9
|
+
/**
|
|
10
|
+
* Obtiene el último número de comprobante autorizado para un punto de venta y tipo.
|
|
11
|
+
*/
|
|
12
|
+
ultimoComprobante(auth: WsfeAuth, ptoVta: number, cbteTipo: number): Promise<number>;
|
|
13
|
+
/**
|
|
14
|
+
* Consulta un comprobante previamente autorizado.
|
|
15
|
+
*/
|
|
16
|
+
consultarComprobante(auth: WsfeAuth, cbteTipo: number, ptoVta: number, cbteNro: number): Promise<FECompConsultarResult>;
|
|
17
|
+
/**
|
|
18
|
+
* Verifica el estado de los servidores de ARCA.
|
|
19
|
+
*/
|
|
20
|
+
serverStatus(): Promise<ServerStatus>;
|
|
21
|
+
/**
|
|
22
|
+
* Obtiene los tipos de comprobante disponibles.
|
|
23
|
+
*/
|
|
24
|
+
getTiposComprobante(auth: WsfeAuth): Promise<ParamItem[]>;
|
|
25
|
+
/**
|
|
26
|
+
* Obtiene los tipos de documento disponibles.
|
|
27
|
+
*/
|
|
28
|
+
getTiposDocumento(auth: WsfeAuth): Promise<ParamItem[]>;
|
|
29
|
+
/**
|
|
30
|
+
* Obtiene los tipos de IVA disponibles.
|
|
31
|
+
*/
|
|
32
|
+
getTiposIva(auth: WsfeAuth): Promise<ParamItem[]>;
|
|
33
|
+
/**
|
|
34
|
+
* Obtiene las monedas disponibles.
|
|
35
|
+
*/
|
|
36
|
+
getMonedas(auth: WsfeAuth): Promise<MonedaItem[]>;
|
|
37
|
+
/**
|
|
38
|
+
* Obtiene los tipos de tributo disponibles.
|
|
39
|
+
*/
|
|
40
|
+
getTiposTributo(auth: WsfeAuth): Promise<ParamItem[]>;
|
|
41
|
+
/**
|
|
42
|
+
* Obtiene los tipos de opcionales disponibles.
|
|
43
|
+
*/
|
|
44
|
+
getTiposOpcional(auth: WsfeAuth): Promise<ParamItem[]>;
|
|
45
|
+
/**
|
|
46
|
+
* Obtiene los puntos de venta habilitados.
|
|
47
|
+
*/
|
|
48
|
+
getPuntosVenta(auth: WsfeAuth): Promise<PtoVentaItem[]>;
|
|
49
|
+
/**
|
|
50
|
+
* Obtiene la cotización de una moneda.
|
|
51
|
+
*/
|
|
52
|
+
getCotizacion(auth: WsfeAuth, monedaId: string): Promise<CotizacionResult>;
|
|
53
|
+
/**
|
|
54
|
+
* Obtiene la cantidad máxima de registros por request de FECAESolicitar.
|
|
55
|
+
*/
|
|
56
|
+
getCantMaxRegistros(auth: WsfeAuth): Promise<number>;
|
|
57
|
+
private buildDetRequest;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=wsfe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wsfe.d.ts","sourceRoot":"","sources":["../src/wsfe.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,QAAQ,EACR,cAAc,EAEd,oBAAoB,EAEpB,qBAAqB,EACrB,YAAY,EACZ,SAAS,EACT,UAAU,EACV,YAAY,EACZ,gBAAgB,EAEjB,MAAM,YAAY,CAAC;AAepB,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAS;gBAEb,UAAU,EAAE,OAAO;IAU/B;;OAEG;IACG,YAAY,CAChB,IAAI,EAAE,QAAQ,EACd,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,oBAAoB,CAAC;IA4BhC;;OAEG;IACG,iBAAiB,CACrB,IAAI,EAAE,QAAQ,EACd,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC;IAelB;;OAEG;IACG,oBAAoB,CACxB,IAAI,EAAE,QAAQ,EACd,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,qBAAqB,CAAC;IAkBjC;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,YAAY,CAAC;IAK3C;;OAEG;IACG,mBAAmB,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAW/D;;OAEG;IACG,iBAAiB,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAW7D;;OAEG;IACG,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAWvD;;OAEG;IACG,UAAU,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAWvD;;OAEG;IACG,eAAe,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAW3D;;OAEG;IACG,gBAAgB,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAW5D;;OAEG;IACG,cAAc,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAW7D;;OAEG;IACG,aAAa,CACjB,IAAI,EAAE,QAAQ,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,gBAAgB,CAAC;IAc5B;;OAEG;IACG,mBAAmB,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;IAc1D,OAAO,CAAC,eAAe;CAsExB"}
|
package/dist/wsfe.js
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { ENDPOINTS } from "./constants.js";
|
|
2
|
+
import { wsfeSoapCall } from "./soap-client.js";
|
|
3
|
+
function toArray(val) {
|
|
4
|
+
if (val === undefined || val === null)
|
|
5
|
+
return [];
|
|
6
|
+
return Array.isArray(val) ? val : [val];
|
|
7
|
+
}
|
|
8
|
+
function checkErrors(result) {
|
|
9
|
+
if (result.Errors) {
|
|
10
|
+
const errs = toArray(result.Errors.Err);
|
|
11
|
+
const msg = errs.map((e) => `[${e.Code}] ${e.Msg}`).join("; ");
|
|
12
|
+
throw new Error(`WSFE Error: ${msg}`);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export class WsfeClient {
|
|
16
|
+
endpoint;
|
|
17
|
+
constructor(production) {
|
|
18
|
+
this.endpoint = production
|
|
19
|
+
? ENDPOINTS.wsfe.production
|
|
20
|
+
: ENDPOINTS.wsfe.testing;
|
|
21
|
+
}
|
|
22
|
+
// ============================================================
|
|
23
|
+
// Facturación
|
|
24
|
+
// ============================================================
|
|
25
|
+
/**
|
|
26
|
+
* Solicita CAE (Código de Autorización Electrónica) para uno o más comprobantes.
|
|
27
|
+
*/
|
|
28
|
+
async solicitarCAE(auth, request) {
|
|
29
|
+
const detRequests = request.invoices.map((inv) => this.buildDetRequest(inv));
|
|
30
|
+
const params = {
|
|
31
|
+
Auth: auth,
|
|
32
|
+
FeCAEReq: {
|
|
33
|
+
FeCabReq: {
|
|
34
|
+
CantReg: request.invoices.length,
|
|
35
|
+
PtoVta: request.PtoVta,
|
|
36
|
+
CbteTipo: request.CbteTipo,
|
|
37
|
+
},
|
|
38
|
+
FeDetReq: {
|
|
39
|
+
FECAEDetRequest: detRequests,
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
const result = (await wsfeSoapCall(this.endpoint, "FECAESolicitar", params));
|
|
44
|
+
return result;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Obtiene el último número de comprobante autorizado para un punto de venta y tipo.
|
|
48
|
+
*/
|
|
49
|
+
async ultimoComprobante(auth, ptoVta, cbteTipo) {
|
|
50
|
+
const result = (await wsfeSoapCall(this.endpoint, "FECompUltimoAutorizado", {
|
|
51
|
+
Auth: auth,
|
|
52
|
+
PtoVta: ptoVta,
|
|
53
|
+
CbteTipo: cbteTipo,
|
|
54
|
+
}));
|
|
55
|
+
checkErrors(result);
|
|
56
|
+
return result.CbteNro;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Consulta un comprobante previamente autorizado.
|
|
60
|
+
*/
|
|
61
|
+
async consultarComprobante(auth, cbteTipo, ptoVta, cbteNro) {
|
|
62
|
+
const result = (await wsfeSoapCall(this.endpoint, "FECompConsultar", {
|
|
63
|
+
Auth: auth,
|
|
64
|
+
FeCompConsReq: {
|
|
65
|
+
CbteTipo: cbteTipo,
|
|
66
|
+
CbteNro: cbteNro,
|
|
67
|
+
PtoVta: ptoVta,
|
|
68
|
+
},
|
|
69
|
+
}));
|
|
70
|
+
checkErrors(result);
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
// ============================================================
|
|
74
|
+
// Parámetros
|
|
75
|
+
// ============================================================
|
|
76
|
+
/**
|
|
77
|
+
* Verifica el estado de los servidores de ARCA.
|
|
78
|
+
*/
|
|
79
|
+
async serverStatus() {
|
|
80
|
+
const result = await wsfeSoapCall(this.endpoint, "FEDummy", {});
|
|
81
|
+
return result;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Obtiene los tipos de comprobante disponibles.
|
|
85
|
+
*/
|
|
86
|
+
async getTiposComprobante(auth) {
|
|
87
|
+
const result = await wsfeSoapCall(this.endpoint, "FEParamGetTiposCbte", { Auth: auth });
|
|
88
|
+
checkErrors(result);
|
|
89
|
+
const items = result.ResultGet?.CbteTipo;
|
|
90
|
+
return toArray(items);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Obtiene los tipos de documento disponibles.
|
|
94
|
+
*/
|
|
95
|
+
async getTiposDocumento(auth) {
|
|
96
|
+
const result = await wsfeSoapCall(this.endpoint, "FEParamGetTiposDoc", { Auth: auth });
|
|
97
|
+
checkErrors(result);
|
|
98
|
+
const items = result.ResultGet?.DocTipo;
|
|
99
|
+
return toArray(items);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Obtiene los tipos de IVA disponibles.
|
|
103
|
+
*/
|
|
104
|
+
async getTiposIva(auth) {
|
|
105
|
+
const result = await wsfeSoapCall(this.endpoint, "FEParamGetTiposIva", { Auth: auth });
|
|
106
|
+
checkErrors(result);
|
|
107
|
+
const items = result.ResultGet?.IvaTipo;
|
|
108
|
+
return toArray(items);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Obtiene las monedas disponibles.
|
|
112
|
+
*/
|
|
113
|
+
async getMonedas(auth) {
|
|
114
|
+
const result = await wsfeSoapCall(this.endpoint, "FEParamGetTiposMonedas", { Auth: auth });
|
|
115
|
+
checkErrors(result);
|
|
116
|
+
const items = result.ResultGet?.Moneda;
|
|
117
|
+
return toArray(items);
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Obtiene los tipos de tributo disponibles.
|
|
121
|
+
*/
|
|
122
|
+
async getTiposTributo(auth) {
|
|
123
|
+
const result = await wsfeSoapCall(this.endpoint, "FEParamGetTiposTributos", { Auth: auth });
|
|
124
|
+
checkErrors(result);
|
|
125
|
+
const items = result.ResultGet?.TributoTipo;
|
|
126
|
+
return toArray(items);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Obtiene los tipos de opcionales disponibles.
|
|
130
|
+
*/
|
|
131
|
+
async getTiposOpcional(auth) {
|
|
132
|
+
const result = await wsfeSoapCall(this.endpoint, "FEParamGetTiposOpcional", { Auth: auth });
|
|
133
|
+
checkErrors(result);
|
|
134
|
+
const items = result.ResultGet?.OpcionalTipo;
|
|
135
|
+
return toArray(items);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Obtiene los puntos de venta habilitados.
|
|
139
|
+
*/
|
|
140
|
+
async getPuntosVenta(auth) {
|
|
141
|
+
const result = await wsfeSoapCall(this.endpoint, "FEParamGetPtosVenta", { Auth: auth });
|
|
142
|
+
checkErrors(result);
|
|
143
|
+
const items = result.ResultGet?.PtoVenta;
|
|
144
|
+
return toArray(items);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Obtiene la cotización de una moneda.
|
|
148
|
+
*/
|
|
149
|
+
async getCotizacion(auth, monedaId) {
|
|
150
|
+
const result = (await wsfeSoapCall(this.endpoint, "FEParamGetCotizacion", {
|
|
151
|
+
Auth: auth,
|
|
152
|
+
MonId: monedaId,
|
|
153
|
+
}));
|
|
154
|
+
checkErrors(result);
|
|
155
|
+
return result;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Obtiene la cantidad máxima de registros por request de FECAESolicitar.
|
|
159
|
+
*/
|
|
160
|
+
async getCantMaxRegistros(auth) {
|
|
161
|
+
const result = await wsfeSoapCall(this.endpoint, "FECompTotXRequest", { Auth: auth });
|
|
162
|
+
checkErrors(result);
|
|
163
|
+
return result.RegXReq ?? 0;
|
|
164
|
+
}
|
|
165
|
+
// ============================================================
|
|
166
|
+
// Helpers
|
|
167
|
+
// ============================================================
|
|
168
|
+
buildDetRequest(inv) {
|
|
169
|
+
const det = {
|
|
170
|
+
Concepto: inv.Concepto,
|
|
171
|
+
DocTipo: inv.DocTipo,
|
|
172
|
+
DocNro: inv.DocNro,
|
|
173
|
+
CbteDesde: inv.CbteDesde,
|
|
174
|
+
CbteHasta: inv.CbteHasta,
|
|
175
|
+
CbteFch: inv.CbteFch,
|
|
176
|
+
ImpTotal: inv.ImpTotal,
|
|
177
|
+
ImpTotConc: inv.ImpTotConc,
|
|
178
|
+
ImpNeto: inv.ImpNeto,
|
|
179
|
+
ImpOpEx: inv.ImpOpEx,
|
|
180
|
+
ImpTrib: inv.ImpTrib,
|
|
181
|
+
ImpIVA: inv.ImpIVA,
|
|
182
|
+
MonId: inv.MonId,
|
|
183
|
+
MonCotiz: inv.MonCotiz,
|
|
184
|
+
};
|
|
185
|
+
if (inv.FchServDesde)
|
|
186
|
+
det.FchServDesde = inv.FchServDesde;
|
|
187
|
+
if (inv.FchServHasta)
|
|
188
|
+
det.FchServHasta = inv.FchServHasta;
|
|
189
|
+
if (inv.FchVtoPago)
|
|
190
|
+
det.FchVtoPago = inv.FchVtoPago;
|
|
191
|
+
if (inv.Iva && inv.Iva.length > 0) {
|
|
192
|
+
det.Iva = {
|
|
193
|
+
AlicIva: inv.Iva.map((i) => ({
|
|
194
|
+
Id: i.Id,
|
|
195
|
+
BaseImp: i.BaseImp,
|
|
196
|
+
Importe: i.Importe,
|
|
197
|
+
})),
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
if (inv.Tributos && inv.Tributos.length > 0) {
|
|
201
|
+
det.Tributos = {
|
|
202
|
+
Tributo: inv.Tributos.map((t) => ({
|
|
203
|
+
Id: t.Id,
|
|
204
|
+
Desc: t.Desc,
|
|
205
|
+
BaseImp: t.BaseImp,
|
|
206
|
+
Alic: t.Alic,
|
|
207
|
+
Importe: t.Importe,
|
|
208
|
+
})),
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
if (inv.CbtesAsoc && inv.CbtesAsoc.length > 0) {
|
|
212
|
+
det.CbtesAsoc = {
|
|
213
|
+
CbteAsoc: inv.CbtesAsoc.map((c) => {
|
|
214
|
+
const asoc = {
|
|
215
|
+
Tipo: c.Tipo,
|
|
216
|
+
PtoVta: c.PtoVta,
|
|
217
|
+
Nro: c.Nro,
|
|
218
|
+
};
|
|
219
|
+
if (c.Cuit)
|
|
220
|
+
asoc.Cuit = c.Cuit;
|
|
221
|
+
if (c.CbteFch)
|
|
222
|
+
asoc.CbteFch = c.CbteFch;
|
|
223
|
+
return asoc;
|
|
224
|
+
}),
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
if (inv.Opcionales && inv.Opcionales.length > 0) {
|
|
228
|
+
det.Opcionales = {
|
|
229
|
+
Opcional: inv.Opcionales.map((o) => ({
|
|
230
|
+
Id: o.Id,
|
|
231
|
+
Valor: o.Valor,
|
|
232
|
+
})),
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
return det;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
//# sourceMappingURL=wsfe.js.map
|
package/dist/wsfe.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wsfe.js","sourceRoot":"","sources":["../src/wsfe.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ramiidv/arca-sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "SDK para interactuar con los Web Services de ARCA (ex AFIP) - Facturación Electrónica Argentina",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"README.md",
|
|
17
|
+
"LICENSE"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc",
|
|
21
|
+
"dev": "tsc --watch",
|
|
22
|
+
"prepublishOnly": "npm run build"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"afip",
|
|
26
|
+
"arca",
|
|
27
|
+
"factura-electronica",
|
|
28
|
+
"wsfe",
|
|
29
|
+
"wsaa",
|
|
30
|
+
"argentina",
|
|
31
|
+
"cae",
|
|
32
|
+
"invoice",
|
|
33
|
+
"factura",
|
|
34
|
+
"mipyme",
|
|
35
|
+
"fce",
|
|
36
|
+
"soap",
|
|
37
|
+
"tax"
|
|
38
|
+
],
|
|
39
|
+
"license": "MIT",
|
|
40
|
+
"repository": {
|
|
41
|
+
"type": "git",
|
|
42
|
+
"url": "https://github.com/ramiidv/arca-sdk.git"
|
|
43
|
+
},
|
|
44
|
+
"homepage": "https://github.com/ramiidv/arca-sdk#readme",
|
|
45
|
+
"bugs": {
|
|
46
|
+
"url": "https://github.com/ramiidv/arca-sdk/issues"
|
|
47
|
+
},
|
|
48
|
+
"engines": {
|
|
49
|
+
"node": ">=18.0.0"
|
|
50
|
+
},
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"node-forge": "^1.3.1",
|
|
53
|
+
"fast-xml-parser": "^5.1.0"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@types/node": "^22.0.0",
|
|
57
|
+
"@types/node-forge": "^1.3.11",
|
|
58
|
+
"typescript": "^5.7.0"
|
|
59
|
+
}
|
|
60
|
+
}
|