arca-sdk 1.0.4 → 1.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/CHANGELOG.md +13 -0
- package/README.md +27 -1
- package/dist/index.cjs +160 -41
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +143 -5
- package/dist/index.d.ts +143 -5
- package/dist/index.js +160 -41
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,19 @@ Todos los cambios notables de este proyecto se documentan en este archivo.
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
## [1.1.0] — 2026-02-28
|
|
8
|
+
|
|
9
|
+
### ✨ Nuevos Comprobantes (Vouchers)
|
|
10
|
+
|
|
11
|
+
Se expandió la funcionalidad del servicio de facturación (`WsfeService`) para cubrir el espectro completo de comprobantes básicos:
|
|
12
|
+
|
|
13
|
+
- **Notas de Crédito**: Agregados métodos `issueCreditNoteA()`, `issueCreditNoteB()` y `issueCreditNoteC()`.
|
|
14
|
+
- **Notas de Débito**: Agregados métodos `issueDebitNoteA()`, `issueDebitNoteB()` y `issueDebitNoteC()`.
|
|
15
|
+
- **Recibos**: Agregados métodos `issueReceiptA()`, `issueReceiptB()` y `issueReceiptC()`.
|
|
16
|
+
- **Comprobantes Asociados**: El SDK ahora genera correctamente el nodo `<ar:CbtesAsoc>` de forma obligatoria para emitir NC/ND, asegurando que la operación de contingencia (anulación total o parcial de una factura) respete el estándar del ente recaudador.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
7
20
|
## [1.0.4] — 2026-02-27
|
|
8
21
|
|
|
9
22
|
### 🐛 Bugfix — Timezone Handling
|
package/README.md
CHANGED
|
@@ -127,9 +127,12 @@ console.log('QR:', result.qrUrl); // 'https://www.afip.gob.ar/fe/qr/
|
|
|
127
127
|
|--------|-------------|---------------|
|
|
128
128
|
| `issueSimpleReceipt()` | Ticket C | Monto total, sin detalle. Ideal para POS simple |
|
|
129
129
|
| `issueReceipt()` | Ticket C + items | Con detalle de productos guardado localmente |
|
|
130
|
-
| `issueInvoiceC()` | Factura C | Monotributistas a consumidor final |
|
|
130
|
+
| `issueInvoiceC()` | Factura C | Monotributistas a consumidor final / Empresas |
|
|
131
131
|
| `issueInvoiceB()` | Factura B | Responsable Inscripto a consumidor final / Monotributo |
|
|
132
132
|
| `issueInvoiceA()` | Factura A | Responsable Inscripto a Responsable Inscripto |
|
|
133
|
+
| `issueCreditNoteA/B/C()` | Nota de Crédito | Anulación/Devolución (Requiere asociar la factura original) |
|
|
134
|
+
| `issueDebitNoteA/B/C()` | Nota de Débito | Cobro extra/Penalidad (Requiere asociar la factura original) |
|
|
135
|
+
| `issueReceiptA/B/C()` | Recibo | Comprobante de pago (misma emisión que una factura) |
|
|
133
136
|
|
|
134
137
|
### ✅ Consultas disponibles
|
|
135
138
|
|
|
@@ -180,6 +183,26 @@ result.vat?.forEach(v => {
|
|
|
180
183
|
});
|
|
181
184
|
```
|
|
182
185
|
|
|
186
|
+
### Nota de Crédito (Anulando factura previa)
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
import { InvoiceType } from 'arca-sdk';
|
|
190
|
+
|
|
191
|
+
const result = await wsfe.issueCreditNoteC({
|
|
192
|
+
items: [
|
|
193
|
+
{ description: 'Anulación de equipo defectuoso', quantity: 1, unitPrice: 45000 },
|
|
194
|
+
],
|
|
195
|
+
// ⚠️ Obligatorio en NC/ND: especificar el comprobante original afectado
|
|
196
|
+
associatedInvoices: [{
|
|
197
|
+
type: InvoiceType.FACTURA_C, // La factura que estoy anulando
|
|
198
|
+
pointOfSale: 4,
|
|
199
|
+
invoiceNumber: 15302,
|
|
200
|
+
}],
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
console.log('CAE de anulación:', result.cae);
|
|
204
|
+
```
|
|
205
|
+
|
|
183
206
|
### Consulta de Padrón A13
|
|
184
207
|
|
|
185
208
|
```typescript
|
|
@@ -270,6 +293,9 @@ try {
|
|
|
270
293
|
}
|
|
271
294
|
```
|
|
272
295
|
|
|
296
|
+
### 🚚 Acerca de los Remitos
|
|
297
|
+
> **¡Atención!** Este SDK implementa nativamente el servicio `WSFE` (Facturación Electrónica). Si tu negocio necesita emitir **Remitos Electrónicos Oficiales** para el traslado físico de mercaderías (Remitos Cárnicos, Azucareros, Harineros, etc.), tené en cuenta que la AFIP exige usar un webservice totalmente distinto llamado `WSREM` o similares. Estos servicios aún no están cubiertos por esta versión del SDK.
|
|
298
|
+
|
|
273
299
|
---
|
|
274
300
|
|
|
275
301
|
## Compatibilidad
|
package/dist/index.cjs
CHANGED
|
@@ -507,8 +507,17 @@ var WsaaService = class {
|
|
|
507
507
|
// src/types/wsfe.ts
|
|
508
508
|
var InvoiceType = /* @__PURE__ */ ((InvoiceType2) => {
|
|
509
509
|
InvoiceType2[InvoiceType2["FACTURA_A"] = 1] = "FACTURA_A";
|
|
510
|
+
InvoiceType2[InvoiceType2["NOTA_DEBITO_A"] = 2] = "NOTA_DEBITO_A";
|
|
511
|
+
InvoiceType2[InvoiceType2["NOTA_CREDITO_A"] = 3] = "NOTA_CREDITO_A";
|
|
512
|
+
InvoiceType2[InvoiceType2["RECIBO_A"] = 4] = "RECIBO_A";
|
|
510
513
|
InvoiceType2[InvoiceType2["FACTURA_B"] = 6] = "FACTURA_B";
|
|
514
|
+
InvoiceType2[InvoiceType2["NOTA_DEBITO_B"] = 7] = "NOTA_DEBITO_B";
|
|
515
|
+
InvoiceType2[InvoiceType2["NOTA_CREDITO_B"] = 8] = "NOTA_CREDITO_B";
|
|
516
|
+
InvoiceType2[InvoiceType2["RECIBO_B"] = 9] = "RECIBO_B";
|
|
511
517
|
InvoiceType2[InvoiceType2["FACTURA_C"] = 11] = "FACTURA_C";
|
|
518
|
+
InvoiceType2[InvoiceType2["NOTA_DEBITO_C"] = 12] = "NOTA_DEBITO_C";
|
|
519
|
+
InvoiceType2[InvoiceType2["NOTA_CREDITO_C"] = 13] = "NOTA_CREDITO_C";
|
|
520
|
+
InvoiceType2[InvoiceType2["RECIBO_C"] = 15] = "RECIBO_C";
|
|
512
521
|
InvoiceType2[InvoiceType2["TICKET_A"] = 81] = "TICKET_A";
|
|
513
522
|
InvoiceType2[InvoiceType2["TICKET_B"] = 82] = "TICKET_B";
|
|
514
523
|
InvoiceType2[InvoiceType2["TICKET_C"] = 83] = "TICKET_C";
|
|
@@ -737,57 +746,93 @@ var WsfeService = class _WsfeService {
|
|
|
737
746
|
return { ...cae, items: params.items };
|
|
738
747
|
}
|
|
739
748
|
/**
|
|
740
|
-
* Emite una Factura
|
|
749
|
+
* Emite una Factura A (Responsable Inscripto a Responsable Inscripto, con IVA discriminado).
|
|
750
|
+
* REQUIERE `vatRate` en todos los items.
|
|
741
751
|
*/
|
|
742
|
-
async
|
|
743
|
-
|
|
744
|
-
return this.issueDocument({
|
|
745
|
-
type: 11 /* FACTURA_C */,
|
|
746
|
-
concept: params.concept || 1 /* PRODUCTS */,
|
|
747
|
-
total,
|
|
748
|
-
date: params.date,
|
|
749
|
-
buyer: {
|
|
750
|
-
docType: 99 /* FINAL_CONSUMER */,
|
|
751
|
-
docNumber: "0"
|
|
752
|
-
},
|
|
753
|
-
items: params.items
|
|
754
|
-
});
|
|
752
|
+
async issueInvoiceA(params) {
|
|
753
|
+
return this.issueInvoiceWithVAT(1 /* FACTURA_A */, params);
|
|
755
754
|
}
|
|
756
755
|
/**
|
|
757
756
|
* Emite una Factura B (con IVA discriminado).
|
|
758
757
|
* REQUIERE `vatRate` en todos los items.
|
|
759
758
|
*/
|
|
760
759
|
async issueInvoiceB(params) {
|
|
761
|
-
this.
|
|
762
|
-
const includesVAT = params.includesVAT || false;
|
|
763
|
-
const vatData = this.calculateVATByRate(params.items, includesVAT);
|
|
764
|
-
return this.issueDocument({
|
|
765
|
-
type: 6 /* FACTURA_B */,
|
|
766
|
-
concept: params.concept || 1 /* PRODUCTS */,
|
|
767
|
-
items: params.items,
|
|
768
|
-
buyer: params.buyer,
|
|
769
|
-
date: params.date,
|
|
770
|
-
vatData,
|
|
771
|
-
includesVAT
|
|
772
|
-
});
|
|
760
|
+
return this.issueInvoiceWithVAT(6 /* FACTURA_B */, params);
|
|
773
761
|
}
|
|
774
762
|
/**
|
|
775
|
-
* Emite una Factura
|
|
776
|
-
* REQUIERE `vatRate` en todos los items.
|
|
763
|
+
* Emite una Factura C (consumidor final, sin discriminación de IVA).
|
|
777
764
|
*/
|
|
778
|
-
async
|
|
779
|
-
this.
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
765
|
+
async issueInvoiceC(params) {
|
|
766
|
+
return this.issueInvoiceWithoutVAT(11 /* FACTURA_C */, params);
|
|
767
|
+
}
|
|
768
|
+
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
769
|
+
// Recibos
|
|
770
|
+
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
771
|
+
/**
|
|
772
|
+
* Emite un Recibo A (con IVA discriminado).
|
|
773
|
+
*/
|
|
774
|
+
async issueReceiptA(params) {
|
|
775
|
+
return this.issueInvoiceWithVAT(4 /* RECIBO_A */, params);
|
|
776
|
+
}
|
|
777
|
+
/**
|
|
778
|
+
* Emite un Recibo B (con IVA discriminado).
|
|
779
|
+
*/
|
|
780
|
+
async issueReceiptB(params) {
|
|
781
|
+
return this.issueInvoiceWithVAT(9 /* RECIBO_B */, params);
|
|
782
|
+
}
|
|
783
|
+
/**
|
|
784
|
+
* Emite un Recibo C (sin discriminación de IVA).
|
|
785
|
+
*/
|
|
786
|
+
async issueReceiptC(params) {
|
|
787
|
+
return this.issueInvoiceWithoutVAT(15 /* RECIBO_C */, params);
|
|
788
|
+
}
|
|
789
|
+
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
790
|
+
// Notas de Crédito
|
|
791
|
+
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
792
|
+
/**
|
|
793
|
+
* Emite una Nota de Crédito A.
|
|
794
|
+
* REQUIERE especificar la Factura A original en `associatedInvoices`.
|
|
795
|
+
*/
|
|
796
|
+
async issueCreditNoteA(params) {
|
|
797
|
+
return this.issueInvoiceWithVAT(3 /* NOTA_CREDITO_A */, params);
|
|
798
|
+
}
|
|
799
|
+
/**
|
|
800
|
+
* Emite una Nota de Crédito B.
|
|
801
|
+
* REQUIERE especificar la Factura B original en `associatedInvoices`.
|
|
802
|
+
*/
|
|
803
|
+
async issueCreditNoteB(params) {
|
|
804
|
+
return this.issueInvoiceWithVAT(8 /* NOTA_CREDITO_B */, params);
|
|
805
|
+
}
|
|
806
|
+
/**
|
|
807
|
+
* Emite una Nota de Crédito C.
|
|
808
|
+
* REQUIERE especificar la Factura C original en `associatedInvoices`.
|
|
809
|
+
*/
|
|
810
|
+
async issueCreditNoteC(params) {
|
|
811
|
+
return this.issueInvoiceWithoutVAT(13 /* NOTA_CREDITO_C */, params);
|
|
812
|
+
}
|
|
813
|
+
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
814
|
+
// Notas de Débito
|
|
815
|
+
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
816
|
+
/**
|
|
817
|
+
* Emite una Nota de Débito A.
|
|
818
|
+
* REQUIERE especificar la Factura A original en `associatedInvoices`.
|
|
819
|
+
*/
|
|
820
|
+
async issueDebitNoteA(params) {
|
|
821
|
+
return this.issueInvoiceWithVAT(2 /* NOTA_DEBITO_A */, params);
|
|
822
|
+
}
|
|
823
|
+
/**
|
|
824
|
+
* Emite una Nota de Débito B.
|
|
825
|
+
* REQUIERE especificar la Factura B original en `associatedInvoices`.
|
|
826
|
+
*/
|
|
827
|
+
async issueDebitNoteB(params) {
|
|
828
|
+
return this.issueInvoiceWithVAT(7 /* NOTA_DEBITO_B */, params);
|
|
829
|
+
}
|
|
830
|
+
/**
|
|
831
|
+
* Emite una Nota de Débito C.
|
|
832
|
+
* REQUIERE especificar la Factura C original en `associatedInvoices`.
|
|
833
|
+
*/
|
|
834
|
+
async issueDebitNoteC(params) {
|
|
835
|
+
return this.issueInvoiceWithoutVAT(12 /* NOTA_DEBITO_C */, params);
|
|
791
836
|
}
|
|
792
837
|
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
793
838
|
// Consultas
|
|
@@ -918,6 +963,63 @@ var WsfeService = class _WsfeService {
|
|
|
918
963
|
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
919
964
|
// Métodos internos
|
|
920
965
|
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
966
|
+
/**
|
|
967
|
+
* Helper para emitir comprobantes tipo A/B que requieren IVA
|
|
968
|
+
*/
|
|
969
|
+
async issueInvoiceWithVAT(type, params) {
|
|
970
|
+
this.validateItemsWithVAT(params.items);
|
|
971
|
+
this.validateAssociatedInvoices(type, params.associatedInvoices);
|
|
972
|
+
const includesVAT = params.includesVAT || false;
|
|
973
|
+
const vatData = this.calculateVATByRate(params.items, includesVAT);
|
|
974
|
+
return this.issueDocument({
|
|
975
|
+
type,
|
|
976
|
+
concept: params.concept || 1 /* PRODUCTS */,
|
|
977
|
+
items: params.items,
|
|
978
|
+
buyer: params.buyer,
|
|
979
|
+
associatedInvoices: params.associatedInvoices,
|
|
980
|
+
date: params.date,
|
|
981
|
+
vatData,
|
|
982
|
+
includesVAT
|
|
983
|
+
});
|
|
984
|
+
}
|
|
985
|
+
/**
|
|
986
|
+
* Helper para emitir comprobantes tipo C que no discriminan IVA
|
|
987
|
+
*/
|
|
988
|
+
async issueInvoiceWithoutVAT(type, params) {
|
|
989
|
+
this.validateAssociatedInvoices(type, params.associatedInvoices);
|
|
990
|
+
const total = round(calculateTotal(params.items));
|
|
991
|
+
return this.issueDocument({
|
|
992
|
+
type,
|
|
993
|
+
concept: params.concept || 1 /* PRODUCTS */,
|
|
994
|
+
total,
|
|
995
|
+
date: params.date,
|
|
996
|
+
buyer: params.buyer || {
|
|
997
|
+
docType: 99 /* FINAL_CONSUMER */,
|
|
998
|
+
docNumber: "0"
|
|
999
|
+
},
|
|
1000
|
+
items: params.items,
|
|
1001
|
+
associatedInvoices: params.associatedInvoices
|
|
1002
|
+
});
|
|
1003
|
+
}
|
|
1004
|
+
/**
|
|
1005
|
+
* Validación obligatoria para NC/ND
|
|
1006
|
+
*/
|
|
1007
|
+
validateAssociatedInvoices(type, associatedInvoices) {
|
|
1008
|
+
const needsAssociation = [
|
|
1009
|
+
3 /* NOTA_CREDITO_A */,
|
|
1010
|
+
2 /* NOTA_DEBITO_A */,
|
|
1011
|
+
8 /* NOTA_CREDITO_B */,
|
|
1012
|
+
7 /* NOTA_DEBITO_B */,
|
|
1013
|
+
13 /* NOTA_CREDITO_C */,
|
|
1014
|
+
12 /* NOTA_DEBITO_C */
|
|
1015
|
+
].includes(type);
|
|
1016
|
+
if (needsAssociation && (!associatedInvoices || associatedInvoices.length === 0)) {
|
|
1017
|
+
throw new ArcaValidationError(
|
|
1018
|
+
"Las Notas de Cr\xE9dito y D\xE9bito requieren al menos un comprobante asociado.",
|
|
1019
|
+
{ hint: "Debes enviar el arreglo `associatedInvoices` con la factura original a la cual haces referencia" }
|
|
1020
|
+
);
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
921
1023
|
/**
|
|
922
1024
|
* Método genérico interno para emitir cualquier tipo de comprobante.
|
|
923
1025
|
*/
|
|
@@ -942,6 +1044,7 @@ var WsfeService = class _WsfeService {
|
|
|
942
1044
|
concept: request.concept,
|
|
943
1045
|
date: request.date || /* @__PURE__ */ new Date(),
|
|
944
1046
|
buyer: request.buyer,
|
|
1047
|
+
associatedInvoices: request.associatedInvoices,
|
|
945
1048
|
net,
|
|
946
1049
|
vat,
|
|
947
1050
|
total,
|
|
@@ -1087,6 +1190,21 @@ var WsfeService = class _WsfeService {
|
|
|
1087
1190
|
});
|
|
1088
1191
|
vatXml += "\n </ar:Iva>";
|
|
1089
1192
|
}
|
|
1193
|
+
let asocXml = "";
|
|
1194
|
+
if (params.associatedInvoices && params.associatedInvoices.length > 0) {
|
|
1195
|
+
asocXml = "<ar:CbtesAsoc>";
|
|
1196
|
+
params.associatedInvoices.forEach((asoc) => {
|
|
1197
|
+
asocXml += `
|
|
1198
|
+
<ar:CbteAsoc>
|
|
1199
|
+
<ar:Tipo>${asoc.type}</ar:Tipo>
|
|
1200
|
+
<ar:PtoVta>${asoc.pointOfSale}</ar:PtoVta>
|
|
1201
|
+
<ar:Nro>${asoc.invoiceNumber}</ar:Nro>
|
|
1202
|
+
${asoc.cuit ? `<ar:Cuit>${asoc.cuit}</ar:Cuit>` : ""}
|
|
1203
|
+
${asoc.date ? `<ar:CbteFch>${asoc.date.toISOString().split("T")[0].replace(/-/g, "")}</ar:CbteFch>` : ""}
|
|
1204
|
+
</ar:CbteAsoc>`;
|
|
1205
|
+
});
|
|
1206
|
+
asocXml += "\n </ar:CbtesAsoc>";
|
|
1207
|
+
}
|
|
1090
1208
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
1091
1209
|
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
|
|
1092
1210
|
xmlns:ar="http://ar.gov.afip.dif.FEV1/">
|
|
@@ -1120,6 +1238,7 @@ var WsfeService = class _WsfeService {
|
|
|
1120
1238
|
<ar:ImpTrib>0.00</ar:ImpTrib>
|
|
1121
1239
|
<ar:MonId>PES</ar:MonId>
|
|
1122
1240
|
<ar:MonCotiz>1</ar:MonCotiz>
|
|
1241
|
+
${asocXml}
|
|
1123
1242
|
${vatXml}
|
|
1124
1243
|
</ar:FECAEDetRequest>
|
|
1125
1244
|
</ar:FeDetReq>
|