@taxora/sdk 1.9.0 → 1.10.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 +29 -0
- package/README.md +54 -0
- package/dist/index.cjs +692 -236
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +271 -50
- package/dist/index.d.ts +271 -50
- package/dist/index.js +684 -236
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,35 @@ All notable changes to `@taxora/sdk` are documented here. Versions follow [SemVe
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [1.10.0] - 2026-11-03
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- `ComplianceTax.rate()`, `zeroRated()`, `exempt()` and `reverseCharge()` build line taxes with the right category.
|
|
12
|
+
- `calculateInvoiceTotals(lines, { expectedTotal })` checks your own total against the lines and reports `roundingDifference`.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- `createTransaction()` refuses impossible input before the request: an unknown tax category, a category `E` tax
|
|
17
|
+
without its exemption code (`comment`), a percent outside 0–100, a currency or country code that is not letters
|
|
18
|
+
(currency, counterparty country and tax categories are upper-cased), a due date before the invoice date, a credit
|
|
19
|
+
note without `amendedNumber` (or `amendedNumber` without `isCreditNote`), a credit note reusing the number it corrects
|
|
20
|
+
and a corrected invoice dated after the credit note.
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
|
|
24
|
+
- **`eReporting.createCreditNote(original, input)`** — credit an invoice you sent through Taxora. Buyer, lines, amounts,
|
|
25
|
+
currency and the reference to the corrected invoice (number and date) are taken from `original`; partial credits pass
|
|
26
|
+
`invoiceLines`, `subtotal`, `taxAmount` and `total` together. Refused up front for invoices that were never sent
|
|
27
|
+
(`not_required`) and for credit notes.
|
|
28
|
+
- **`eReporting.decideDelivery(country, id, scheme?)`** — `peppolLookup()` turned into an action
|
|
29
|
+
(`ComplianceDeliveryAction`: `einvoice`, `einvoice_pending`, `regular_invoice`) for a shop checkout.
|
|
30
|
+
- **`calculateInvoiceTotals(lines)`** — subtotal, VAT and total of invoice lines, rounded the way the e-invoice is built,
|
|
31
|
+
so the header amounts of `createTransaction()` always match the lines.
|
|
32
|
+
- **`ComplianceTaxCategory`** (`S`, `AA`, `AAA`, `K`, `G`, `AE`, `E`, `Z`) and `parseComplianceTaxCategory()`.
|
|
33
|
+
- **`billing.getEInvoicingQuota(months?)`** — `GET /billing/einvoicing-quota` as `EInvoicingQuota` (documents included,
|
|
34
|
+
used, still free and what is due per month); `null` without e-invoicing.
|
|
35
|
+
|
|
7
36
|
## [1.9.0] — 2026-10-27
|
|
8
37
|
|
|
9
38
|
### Added
|
package/README.md
CHANGED
|
@@ -821,6 +821,41 @@ if (reach.isPending) {
|
|
|
821
821
|
console.log(reach.status, reach.reachable, reach.documentTypes); // 'reachable' true [...]
|
|
822
822
|
```
|
|
823
823
|
|
|
824
|
+
Or let the SDK turn the answer into an action (shop checkout, one call):
|
|
825
|
+
|
|
826
|
+
```ts
|
|
827
|
+
const decision = await client.eReporting.decideDelivery('NO', '974760673');
|
|
828
|
+
switch (decision.action) {
|
|
829
|
+
case 'einvoice': // create the transaction, Taxora sends the e-invoice
|
|
830
|
+
case 'einvoice_pending': // no answer yet: create it anyway, Taxora asks again before sending
|
|
831
|
+
break;
|
|
832
|
+
case 'regular_invoice': // not on Peppol: send your usual invoice, nothing is billed
|
|
833
|
+
break;
|
|
834
|
+
}
|
|
835
|
+
```
|
|
836
|
+
|
|
837
|
+
The SDK refuses input that cannot be right before any request: unknown tax categories
|
|
838
|
+
(`ComplianceTaxCategory`: `S`, `AA`, `AAA`, `K`, `G`, `AE`, `E`, `Z`, any case), a category `E` line without its VATEX
|
|
839
|
+
exemption code, currency and country codes that are not letters (they are upper-cased), a due date before the invoice
|
|
840
|
+
date, and credit notes without (or invoices with) a corrected invoice. The API additionally checks that an e-invoice's
|
|
841
|
+
`subtotal`, `taxAmount` and `total` match its lines — compute them from the lines:
|
|
842
|
+
|
|
843
|
+
```ts
|
|
844
|
+
import { calculateInvoiceTotals } from '@taxora/sdk';
|
|
845
|
+
|
|
846
|
+
const { subtotal, taxAmount, total } = calculateInvoiceTotals(invoiceLines); // rounded like the e-invoice
|
|
847
|
+
```
|
|
848
|
+
|
|
849
|
+
Taxes without remembering category codes: `ComplianceTax.rate(25)` (category `S`, any rate above 0 %; in Norway 25/15/12 % are all `S`, for France's reduced rates pass `ComplianceTax.rate(10, 'TVA', 'AA')`), `zeroRated()` (`Z`),
|
|
850
|
+
`exempt('VATEX-EU-132')` (`E`, code mandatory) and `reverseCharge()` (`AE`). The rate itself is yours to know; the API checks
|
|
851
|
+
it against the country's catalogue. The tax name defaults to `VAT` (`ComplianceTax.rate(25, 'MVA')`).
|
|
852
|
+
|
|
853
|
+
If your own system already shows the buyer a total, pass it as a safety net:
|
|
854
|
+
`calculateInvoiceTotals(lines, { expectedTotal: 1249.99 })`. The totals always follow the lines, because the e-invoice is built
|
|
855
|
+
from them. A difference up to 0.05 is reported as `roundingDifference`; anything larger throws, since then quantities, prices or
|
|
856
|
+
rates are wrong. The invoice number is printed on the buyer's e-invoice and must be unique per enrollment (a different invoice
|
|
857
|
+
with a used number answers `409 invoice_number_taken`).
|
|
858
|
+
|
|
824
859
|
**4. Send an invoice** — Norway requires `transactionType: 'b2b_domestic_outbound'`, the buyer's
|
|
825
860
|
organisation number (`counterpartyRegisterId`) and `counterpartyName` (enforced server-side, 422):
|
|
826
861
|
|
|
@@ -877,6 +912,21 @@ const creditNote = await client.eReporting.createTransaction({
|
|
|
877
912
|
});
|
|
878
913
|
console.log(creditNote.isCreditNote); // true
|
|
879
914
|
|
|
915
|
+
// Shorter and harder to get wrong: credit an invoice you already sent. Buyer, lines, amounts,
|
|
916
|
+
// currency and the reference to the corrected invoice are taken from it.
|
|
917
|
+
const credit = await client.eReporting.createCreditNote(invoice, { creditNoteNumber: 'NO-2026-0001-CN' });
|
|
918
|
+
|
|
919
|
+
// Partial credit: pass the credited lines and all amounts together.
|
|
920
|
+
await client.eReporting.createCreditNote(invoice, {
|
|
921
|
+
creditNoteNumber: 'NO-2026-0001-CN2',
|
|
922
|
+
invoiceLines: [
|
|
923
|
+
{ description: 'Consulting', quantity: 1, price: 1000, taxes: [{ name: 'MVA', percent: 25, category: 'S' }] },
|
|
924
|
+
],
|
|
925
|
+
subtotal: 1000,
|
|
926
|
+
taxAmount: 250,
|
|
927
|
+
total: 1250,
|
|
928
|
+
});
|
|
929
|
+
|
|
880
930
|
// All Norwegian documents
|
|
881
931
|
const noDocs = await client.eReporting.listTransactions({ country: 'NO' });
|
|
882
932
|
```
|
|
@@ -972,6 +1022,10 @@ for (const summary of page) {
|
|
|
972
1022
|
|
|
973
1023
|
const september = await client.billing.getUsageSummaries('2026-09'); // with events; 404 for a period without usage
|
|
974
1024
|
console.log(september[0]?.events.length);
|
|
1025
|
+
|
|
1026
|
+
// E-invoicing allowance: documents included per month, used, still free, what is due beyond it (null without e-invoicing)
|
|
1027
|
+
const quota = await client.billing.getEInvoicingQuota();
|
|
1028
|
+
console.log(quota?.current.freeRemaining, 'of', quota?.current.included, 'documents free this month');
|
|
975
1029
|
```
|
|
976
1030
|
|
|
977
1031
|
---
|